The Craftsmanship of Code

Last week my sister accused me of being a snob. That stung in that special way reserved for jabs that are true; that you wouldn’t change if you could; and that you wish other people wouldn’t notice. In this case I had apparently gagged raised an eyebrow when she told me about her new desk from Ikea.

“Ikea makes schlock,” I said.

“Ikea makes fun, well designed furniture,” she said.

“Ikea makes furniture that will pack flat and not take too much space in the garbage truck in three years when it’s curbed,” I said.

“Ok, so tell me what Good Furniture is like,” she said.

“Um…,” I said.

“Peh.” she said, and threw a grape at me.

Later, I took her to a local furniture gallery, where we looked at some exquisite handcrafted furniture in the Krenov style. “OK,” she said, “I get it. But you’re still a snob.”

Craftsmanship is like that. It’s difficult to pin down with labels, but it’s evident when you see it. Its absence is also evident. And once exposed to true craftsmanship, it’s hard to be satisfied with anything else, no matter how flat it packs.

Craftsmanship in Programming

There’s currently a schism in the software developer community around the issue of craftsmanship. My degree is in Computer Engineering with a software stream, and the philosophy there was definitely that “craftsmanship” was a dangerous and juvenile concept in software. You don’t want the guy building a bridge to be a “craftsman”, you want him to know the math. Why is software any different? Gather the requirements using ISO certified processes; identify and mitigate risks; design; develop; test; lather; rinse; repeat.

On the opposite side of the continuum are folks who spend a Saturday night bar session debating the aesthetics of various iterator constructions, look up, and notice it’s Tuesday. Like all sensitive artists, these folks tend to move around a bit with the fashion of the day (“Oh, puhleeze. Closures are so 2005.”) and engage in self-indulgent behavior that would get you ostracized if you weren’t wearing a beret. They’re also more fun to hang out with than the bankers.

So is software development craftsmanship? Is it engineering? I think this is an important question, because its answer defines what it means to be an excellent programmer. The most balanced discussion I’ve come across is Joel Spolsky’s discussion on programming as Design. He argues that beautiful code, which we often call craftsmanship, is actually a matter of good design – design in the “wow, that’s a beautiful bridge” sense. His essay is excellent, but I think it is incomplete. Redefining craftsmanship in terms of the external qualities of the product is enlightening, but it’s not everything. It doesn’t explain why some code is more aesthetically excellent than other code. It doesn’t explain why the recursive function that Jamie wrote is so much sweeter than the unwrapped for loop that Frank churned out. Frank’s is even 20ms faster! But it’s crap anyhow.

Slow Down Here

So, here’s the meat of this essay: if you’re skimming, slow down for just a second. I’ll tell you when you can speed up again. Here’s the thing: this debate is not new, and it wasn’t invented by computer programmers. Back in the day, prior to the industrial revolution, there was no debate about whether something was craftsmanship: Everything was crafted, it was just crafted well or crafted poorly. During the mid 19th century, furniture began to be pumped out by factories using mass production techniques. This was good for most people, who could now afford a chair instead of the stump they hauled inside, but bad for craftsmen, who watched traditional knowledge and techniques disappear. The product was also inferior. The “Craftsman” style of furniture was a direct response to mass-produced furniture, as idealists formed communes to produce high quality, honest goods using traditional techniques. (In one of history’s better ironies, the only place you can now buy Craftsman furniture is Wal*Mart and Costco.)

In the mid 20th century mass produced furniture, pottery, wood bowls, etc. were the norm. Yet people were still hand making these items, and consumers often preferred the hand made articles even if they were functionally equivalent. “Hand Made” has become a badge of quality, even if human hands are far less accurate than water jets when cutting furniture joints. People debated whether it was sentimentality; marketing; or something else. Until one David Pye, a professor at the London College of Art, published The Nature and Art of Workmanship. This book is a must-read for everyone who believes that software is more than an assembly of components, simply a alternative view of the requirements. It provides excellent and deep coverage of what we mean by “craftsmanship”, and its lessons will make you a better programmer.

Skimmers can speed up again. After you buy the book.

OK, Speed Up Again

Although there are many lessons in Pye’s book, there are two key theses I’ll highlight here in order to add to Joel’s assertion that software craftsmanship is design.

1. The Workmanship of Risk

Pye argued that craftsmanship was not a binary thing that was present or not in an object. One way to think about craftsmanship was with relation to the risk of the operation. What he means by risk is the proximity of the craftsman to the fate of the product, or the extent to which the craftsman’s skills will directly impact the fate of the product. For example, cutting a piece of wood with a computer controlled router has almost no risk associated with the craftsman. Cutting it with a table saw has more risk: a slip in feeding the wood could ruin the workpiece. Cutting it with a wide handsaw has yet more risk, while carving with a chisel carries the most risk of all – the entire operation is unguided by anything except the makers’ hand and skill.

It isn’t hard to see an analogy in programming. One comes from tools. A programmer using a visual builder and hooking up components using VB has little risk: there may be a bug in the tool, or some misspellings, but most likely the program will run as expected. Compare that to programming in assembler, where it is man and machine. One slip, one transposed digit and the program crashes, probably during the demo.

Nobody programs in assembler of course, just as nobody cuts a plank to width with a chisel. But somehow we know that the programmer who slips effortlessly between C and Ruby, simply choosing the best tool for the job, is more of a craftsman than the VB-or-bust guy in the basement. The former is more willing to accept the risk of his craft. He has the confidence and the ability to pick up the chisel when he needs it, and he does not need to design his furniture around the capabilities of the computer router.

2. The scaling of aesthetics

The second thesis of Pye’s that has immediate relevance to programming is the scaling of aesthetics. Consider a skyscraper of exceptional beauty. When you are one kilometer away, you notice its shape, its overall form, and perhaps its relationship to its geography. Come closer, to 500 meters, and the overall form that was beautiful at 1km fades away. But in a seamless progression, it is replaced by the relationship of base to the tower; by the shape of the windows and the color and shadows of the building’s facets. Come in to 100 meters and you can no longer see the overall form or the way the windows gradually narrow as they reach the top; but you can see the form of the facade and the shape of the front entrance, and the way the glass faces to encourage your eye to sweep across the ground level. Come up to one meter and all of that dissolves, but is replaced by the texture of the surfaces and the choices of materials.

The point is that the architect did not consider beauty only at one scale; as one changes scale, different scales of aesthetics emerge, gradually replacing one another in appropriate sequence. No scale is out of place, and every scale has its own merits. The good design morphs as you approach and retreat, surprising and delighting you with new aspects of its beauty.

Consider software. The furthest you can stand from software is as a user, and here you see the design of the user interface; the choices of color, and how well the software anticipates the user’s needs and actions. This is the craftsmanship that Joel describes, and he’s spot on.

But as a programmer, you can move in. You can see the overall architecture of the software, the lack of coupling or spurious dependencies. Move in further and you can see the way the programmer used only RESTful calls in his data access layer, and the grace that affords to the module. Move in again and you’ll see Jamie’s recursive algorithm: only ten line, with symmetrical identation, looking like a wave on the page. But move in to one meter and you see the texture of that call; the multilayered complexity of the recursion that enables the simplicity at another scale.

The craftsmanship is in the unified whole, the way one scale of aesthetic seamlessly blends into the next.

Programming IS Craft

My conclusion, of course, is that creating software is craftsmanship. Not in the way it’s usually meant, which is often just a catch-all word for “it’s not exactly science, but not exactly art either”. Programming can be craftsmanship in a deep, profound way. Not everyone who creates software is a craftsman, and nor should they be: if we didn’t have mass-produced furniture I’d be writing this sitting cross-legged on the floor in my thatch hut. But there is a place for craftsmanship in software, and once you’ve seen it, you may never be satisfied with code generators again.