Monday, March 2, 2009

Code Is Like Waffles: You Should Throw The First Batch Away

My old pal Esther wrote an essay for JavaWorld about throwing away code. She makes the reasonable point that it takes a couple of tries to get code right. And if you take away an irreducible truth, it should be that if you are a great programmer, throwing away code is trivial.

You can learn that from any trade or art, by the way: To a great painter, it's nothing to dash off a masterpiece and use it to pay the rent; my mom crafts the most gorgeous quilts and hands them away almost immediately; for the guy who made my treadmill desk, to do so was a trifle. And I do this with code. In my last really big project, I used to write 1,000 lines of code in a (six-hour) day, unless I was throwing away hundreds of lines. (I had two metrics: How much code I could write, and how much I could throw away without losing functionality.)

If you can do something expertly--in order to be able to do it expertly, you must be able to do it easily. This isn't to say there aren't challenges for experts. But once you understand how things are done, you know how to approach and solve problems in your domain.

But note, that also contradicts the "three tries" notion at some level, or rather the conclusion that Esther draws from it, which is that programs peak at the third version.

First: Sometimes you do grasp a problem right off the bat and hit it out of the park. Subsequent versions are refinements without any real dramatic redesign.

Second: Any program of any complexity--note that Esther uses Windows as an example--is composed of various parts, and as a programmer, you have different levels of comfort with each part, most likely. Windows 3.0, for example, featured memory management code that--well, what attempt was that? And however many tries had been made, was it really the same number as had been done for device drivers? Threading? Microsoft didn't get threading right in Windows 3.x, in the early versions of OS/2, or in Windows 9x. It wasn't until N/T--built by a different crew--that MS managed threading that was less than embarrassing.

Now consider gaming: id made Commander Keen, Castle Wolfenstein and Doom. Was Doom the version 3? Keen was a side-scroller, and all three games were hits, and were fun. The programmers had been working on games previously, too, and Keen was the big breakthrough. Three tries? Note also that the id guys start over every time! They're constantly exploring the boundaries on the domain they're working in, and yet--from a standpoint of technical achievement--they're always successful.

Even if you're not pushing the envelope like those guys, the odds are your problem domain won't break down neatly in ways that allow you to say, "This is the true version three."

Third: Esther talks about fixing code versus replacing it. It's all very well to replace code, but doing so is often a crutch for coders who don't want to do the hard, unglamorous work of maintaining existing code. It's by far easier--and way more fun--to say, "Well, this is a pile of crap, we need to start over from scratch." Being able to read someone else's code, get into their head, and maintain it well is a rare skill--but it's a worthwhile skill, because without it, you can't tell the difference between code that's bad or wrong and code that you simply don't fully understand the impact of.

Joel Spolsky hits on some of the same points here.

Followers