A telling comment

According to conventional wisdom comments in program code are invariably a good thing, and most programmers write far too few; but programmers tend to resent writing comments. Until recently I thought of this as a classic example of finding it hard to accept good practice, rather like the need for code review and testing, but recently I realised that I was repeatedly finding myself writing a comment, then deleting it and rewriting the code instead.

In fact, I suggest that conventional wisdom is strictly wrong, although many comments are in fact justified by weaknesses of the programming languages we use. My reasoning is as follows: almost all the comments I consider “good” are in fact contractual: either they document a function’s inputs, outputs and side-conditions, or explain how some crucial or possibly doubtful code respectively ensures or does not prevent the contract being fulfilled. The problem with such comments is that they are not amenable to automatic checking. Some languages allow at least some level of “programming by contract”; using them, the contractual comments can be at least partly written as code.

Bad comments, on the other hand, tend to fall into one of two categories. The first is that which explains or justifies odd or out-and-out wrong incorrect code or design. Clearly in this case the code should be fixed, although economics may prevent it, unless it must be kept the way it is for compatibility. (Even then, careful redesign can often maintain compatibility while fixing problems.) The second class of bad comment is that which explains “cute” code, by which I mean code whose operation is unclear. Such code is typically brief, using language or mathematical tricks, or is written in APL. I hesitate to condemn cute code out of hand, because it is usually satisfying to write, often executes efficiently, and when properly commented can be satisfying to read and understand, and hence be neatly didactic.

There’s one other class of comments that theory would condemn but good practice encourages: narrative comments, which describe what a long stretch of code is doing step by step. Of course, long stretches of code are usually a bad thing, and should be split into smaller units, but occasionally, typically in the initialisation phase of an application, a large number of housekeeping tasks need to be performed, like a recipe; splitting the code up is largely pointless, and comments take the place of unnecessary functions. As with contract comments, this is arguably a problem with typically-used languages; object-orientation advocates would presumably expect such code to be distributed amongst constructors.

Finally, comments can simply be too long: if the comments are much longer than the code, it’s often a sign that conditions mentioned in the comments aren’t being enforced or checked in the code. Or it might just be a sign of bad writing. Programmers need to be able to write prose just as well, if not better, than code.

Reuben Thomas, Summer 2007

Last updated 2007/10/17