Thoughts On Bridging the “Lacuna Humana”

In my previous post, I discussed the semantic gaps that afflict current programming languages. These gaps are caused by tools focusing on syntax and parsing, and mostly neglecting human factors.[1] I’m not just talking about the fact that languages are clumsy for us to use (more about this later); I’m saying that they ignore our need to talk about important realities of software development: security, coding habits, testability, maintenance plans, dependency management, requirements, intellectual property, and much more.

All this stuff falls within our scope of concern, but none of it is describable in our languages. That’s weird. Imagine we hired a general contractor to build our house, and he was great at swinging hammers and leveling studs. But as soon as we asked him questions about building permits or hiring subs or choosing the right kind of concrete for the foundation, he acted like he didn’t have a clue what we were talking about. We’d be likely to end up with lots of false starts, poorly met requirements, endless kludges, tons of frustration, a heavy QA burden. Hmm… That sounds familiar.

I call this lack of semantic continuity the lacuna humana — the human gap.

The good news is, gaps can often be bridged.

image credit: vestman (Flickr)

I promised I would describe a bridge that has a lot of virtues, and I’m going to begin that work here. It might take us a couple posts to get all the way across, though. Thanks for hanging with me…

Continue reading

All I Really Need To Know I Didn’t Learn In Compugarten

I’m glad newly minted software engineers are exposed to data structures, compilers, concurrency, graph theory, assembly language, and the other goodies that constitute a computer science curriculum. All that stuff is important.

But it’s not enough.

Not all classroom material for CS folks should be technical. Photo credit: uniinnsbruck (Flickr).

Since I’m half way to curmudgeon-hood, I frequently find myself lamenting educational blindspots in the young. I’ve even toyed with the idea of teaching at the nearest university, some day when I Have More Time™. If academia would take me, my lesson plans might cover some of the following topics:

Tech Debt, Leverage, and Grandma’s Envelope

In my previous posts about tech debt, I focused on how we can help organizations remember their debts, and on understanding how tech debts are funded and paid back.

Photo credit: Friends of the Earth International (Flickr)

Photo credit: Friends of the Earth International (Flickr)

These topics hit a raw nerve with coders and testers. Those in the trenches often feel very keenly the cost of doing things in a messy way, and it’s common for them to worry that others don’t “get it.”

They’re not wrong to worry.

However, today I’d like to put on my executive hat and discuss tech debt from a perspective that code jockeys sometimes miss, because blindness is not just an executive disease.

Debt as Leverage

When you hear the word “leverage” in business circles, people are talking about debt: a “highly-leveraged” firm is one financing large portions of its strategy through debt; “leveraged buyouts” are transactions where the buyers borrow vast sums of money from a risk-taking lender to take a company private.

Technogeeks (like me): business people are not dumb. Why did they settle on this metaphor of debt as leverage?

The answer is that debt can allow a company to concentrate enough capital in a short enough timeframe to make high-impact strategic moves that would otherwise be impossible. It’s an enabler and multiplier.

Another take on leverage. Image credit: xkcd.

Debt is a fundamental machine in the business toolkit, just as levers are a fundamental machine for mechanical engineers. Almost all businesses use debt to some extent. If a CEO can borrow capital at 9% and produce 12% ROI with it, and Continue reading

Good Code Is Named Right

(Another post in my “What is ‘Good Code’?” series…)

A rose by any other name may smell as sweet, but in software, the names you choose have consequences.

Rosa berberifolia. Photo credit: I Believe I Can Fry (Flickr).

Names can confuse or cohere. In The Mythical Man-Month, Fred Brooks emphasizes the need for code to have “conceptual integrity.” He means that code that should embody a unifying and consistent vision, with minimal distraction or dissonance. Names of classes, functions, applications, interfaces, resources in RESTful URLs — all are a reflection of the code’s cohesiveness or its chaos.

I once worked with an engineer who liked to pull variable names out of the random hopper at the top of his brain: “apple”, “banana”, “ick”… Although his code provoked an occasional snort of amusement, it didn’t do much to guide later readers into a productive mindset.

One way I can distinguish a mediocre engineer from a great one is by the quality of their language–particularly, the names she or he chooses. Mediocre engineers are sloppy and inconsistent in their names, because they undervalue the way their code communicates to human beings. Mediocre engineers think that comments are for humans, and code is for computers. Code, like java or C++ or ruby, doesn’t communicate to computers at all, folks; it has to be turned into op-codes and 1s and 0s before a computer can use it! Code is human language. Comments are like parenthetical asides in normal human speech — needed occasionally, but annoying if they restate the obvious and distract from flow.

Good engineers understand this. It bothers them if something is called a “Controller” in the code, but it fails to implement IController. It bothers them if .ReadLine() doesn’t always read a line of text from a file; when they run across such a function, they are prone to rename it ReadUpToAFullLine() so the function’s semantics are obvious. If they implement a method that calculates a standard deviation, they are likely to name it something like calcStandardDeviation() instead of stdv() or calc(). (This is not about naming conventions, BTW. I don’t have a problem with short forms or whatever casing convention you prefer; I’m just emphasizing clarity.) Code from great engineers says what they mean, and means what they say. Notice how Martin Fowler (a great engineer) takes this for granted as he discusses an appropriate name for a class in Refactoring:

Does the price class represent an algorithm for calculating the price (in which case I prefer to call it Pricer or PricingStrategy), or does it represent a state of the movie (Star Trek X is a new release). At this stage the choice of pattern (and name) reflects how you want to think about the structure. At the moment I’m thinking about this as a state of a movie. If I later decide a strategy communicates my intention better, I will refactor to do this by changing the names.

Somewhere (maybe Scott Meyers?) I remember reading an expert’s lament about people naming classes FooManager, BarManager, etc. His point was that “Manager” says little or nothing about the class’s responsibilities. I agree (although I must admit I’ve written a few XManager classes in my time :-).

Truly great engineers take the language insight of good engineers one step further. Not only do they want clear and consistent names–they want their code to resonate to a unifying metaphor.

In the early days of ecommerce (I was writing CC processing stuff in about 1996), nobody talked about “shopping carts.” You just wrote code that accepted credit cards, and you kept track of what the user wanted to buy until they were ready to pay. You accumulated customer state in your session, or maybe your db, in whatever way you could cobble together. Messy. Once the shopping cart metaphor was introduced, it was easy to see how you could let a customer change quantities at the last minute, handle partial payments with different cards, apply discounts and coupons, and so forth.

The power of metaphor in code is so pervasive that it may be invisible unless you’re looking for it. Good metaphor leaks from coders to their managers and marketers and support staff and tech writers–and because it explains so much, so clearly and concisely, the audience gloms onto it immediately. From there it leaks out to customers and the blogosphere, and we start taking it for granted. Which says more to you: “a software application that lets you pretend to be running a full OS with simulated hardware” or “virtual machine”? How about “self-replicating program that subverts the normal purpose of software” or “virus”?

Action Item

Find a place in code where comments are compensating for a class, function, or variable with a less-than-ideal name, and fix it.

Extra Credit

Find a place in code where you have a weak or inconsistent metaphor. List implications of that metaphor problem. Brainstorm improvements; if one of the improvements seems particularly helpful, implement it.