Coding For Readability
April 6th, 2007Raymond Chen today reminds us that the readbility of code is important. But I’m not sure I agree with his headline/premise:
“Code is read much more often than it is written.”
In my opinion it’s more important for code to be skimmable than readable. This may be a lot of nitpicking over what is just supposed to be a catchy subject for Raymond’s blog, but I find it thought provoking. Let’s say you’ve got 100K of code. It’s OK if 90K of that code is completely unreadable, as long as it never needs to be modified again. That’s a big if, but my point is that the 10K that is actively developed can be well separated from the 90K of unreadable garbage, and you’re in good shape. Your code is skimmable.
In other words, don’t waste your time making already unreadable code “readable.” Just keep it in a dirty subroutine (and subfolder, probably!) where it belongs, and keep your high level code meaningful. I would guess that the vast majority of code in any shipping product has not been “read” in years. The products continue to evolve because they are skimmable. The change-prone portions have naturally eroded away from the giant clumps of unreadable junk.
Which isn’t to say that new code shouldn’t be as readable as possible. Interestingly enough, the article that prompted Raymond’s latest advice was an earlier one advising against BOOL parameters. He makes a good point, in recognizing that BOOL parameters in C or C++ do not often convey the parameter’s true meaning. Here is an area where Objective-C has a huge advantage with its inline-labeled parameters. Consider Raymond’s complaint:
“Even worse is that CreateEvent has two BOOL parameters. Like anybody reading the code later can remember which comes first.”
The Windows API he alludes to has a prototype like this:
HANDLE WINAPI
CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPCTSTR lpName);
So you end up with a call that looks like this:
HANDLE myHandle = CreateEvent(myAttrs, TRUE, FALSE, "Ouch");
Indeed, Raymond was right. What do the TRUE and FALSE mean? The Objective-C equivalent of this CreateEvent method call would look more like:
HANDLE myHandle = [self createEventWithAttributes:myAttrs
withManualResetting:YES
signallingInitialState:NO
eventName:@"Ahh..."];
Damn it feels good to be a Cocoa programmer.
Update: It occurred to me shortly after writing this that when I do write C code, I often overcome this problem by /* inline-commenting */ the parameters. This technique was also described by somebody in the comments on Raymond’s blog.
Update 2: I didn’t think this post through too well before posting it, and now I feel like I’m suffering a bit of the fallout that comes from that. It’s easy to take from my post above that I have a nonchalant attitude about code readability. I meant it more as a riff on Raymond’s headline, and as an opportunity to add my belief that as important as readability is, skimmability is even more important.
Eric Albert wrote a thoughtful reply, to which I was motivated to also reply in his comments. I think my thoughts there might be also serve the permanent record of this entry here:
For the record, I am also in (nearly) complete agreement with Raymond. I mainly disagreed with his premise that code is read more often than it’s written. I don’t think that’s true.
And my opinions about this also come from being a code generalist. In particular, I think of the bugs I fixed in the Mac OS 7-9 days, when some of the ugliest, unreadable code imaginable was involved in the fixing. Often it was the skimmability of the outer layers that made it possible to pinpoint a bug, even if the final fix required cracking open some C file that was autotranslated from Pascal that was auto-translated from 68K Assembly.
In short: a giant code base is referenced much more like the yellow pages than like a novel. In the phone book, it’s nice when all of the entries are readable and well designed, but it’s much more important to be able ot skim to the section you’re most interested in right now.