Why So Unproductive?

The bricklayer metaphor is used as a contrast to talk about the big, orders-of-magnitude differences between good programmers and average programmers. An average programmer can build a simple program in a week, a good programmer can do it in a day, and a superb programmer is done before lunch. No such equivalent seems to exist for bricklayers, says common wisdom, because the process of bricklaying and the path to getting better at it is so simple and straightforward that differences in intellect and fitness have little to do with the outcome.

But the analogy is unfair. Force a programmer to do the equivalent work that a compiler does and you've found your bricklayer again. Give a bricklayer the equivalent of a compiler and now what do you judge him by?

I think that the fabled 10x gap between "average" and superb programmers can be narrowed with training and practice, and that there's no single genetic or circumstantial gift that can account for all of it. The community already recognizes Fred Brooks's observation that there's "no silver bullet"--no single technology or technique that can double productivity--and that each improvement is only incremental. So should we assume this rule doesn't apply to the men and women themselves?

There are really only two intrinsic, non-trainable personality traits that matter: that they genuinely enjoy programming and that they have a good work ethic. When I interview programmers I consider these to be the most important, because after ten years of experience the productivity gap between any two of them won't be 10x, or even 5x, it'll be more like 1.5x or 1.7x. The industry that thinks 10x spreads are "normal" is one that has a problem with hiring and training, a problem I'll discuss at the end of this letter.

First I want to explore some of the acquirable traits and habits that make a superb programmer so productive. Most of them are about avoiding writing any code at all, or avoiding writing the wrong code. Most productivity gains come from eliminating wasted effort, not by increasing speed.

1. Frequent contemplation

Superb programmers never jump into programming or designing a new program without spending time doing nothing first. This is Will Smith letting the other Men-In-Black candidates shoot the crap out of the cardboard aliens before choosing to shoot the little girl with the quantum physics textbooks. Junior programmers instinctively open up an IDE and start writing boilerplate because they think "this is my job" and want to impress and/or avoid getting fired. What they do most of the time is chose the wrong boilerplate template, or re-invent wheels, or brute-force a solution, or enter a tweak-until-it-works loop, or any combination of the above.

They need to be trained to Pause Before Clause. Don't open the IDE, don't start the "New Project Wizard", just think about what you've been asked to do and ask yourself some questions:

Does this program even need to exist at all? Are we trying to solve a perceived problem that's better solved without computers?

Has someone else already written a program that does, or can be modified to do the same thing?

Does the problem look like another that you've once solved in the past?

A good programmer will also take frequent breaks while working on a project, and it's akin to coming up for air and seeing your work from another perspective. The programming equivalent of highway hypnosis is the tweak-until-it-works loop, where he makes a change in the code, runs it to see if it works, and goes back to make another tweak if it doesn't. It's at its most dangerous when each tweak is incrementally successful, so they never get frustrated and spend entire days optimizing code where a bottleneck doesn't exist. From a shoulder-surfer's point of view they are working diligently, but ultimately going nowhere.

Good programmers all eventually pick-up the habit of taking frequent breaks and checking themselves for Zahirian obsessions.

2. Exposure to other programmers' work

The easiest of all to train, and usually the first task their assigned: putting them on bug fixing duty in someone else's code. This is the boxer's one-two punch: have them write their own programs for a while, then have them maintain someone else's for a while, and switch between them every couple of months for a year.

What happens is that in the first cycle they think about the best way to solve small problems, and in the second cycle see how others have solved those problems--for better or worse.