Wednesday, April 27, 2005
Comments Are Not More Important Than Code
Slashdot recently had a link to Jef Raskin's essay "Comments Are More Important Than Code." The use of comments is a stylistic issue that has been coming up at work a lot lately, so I've been clarifying my own thinking on the issue.
I am firmly in the minimal-commenting camp. That is, I think code can and should be readable with few comments. Code that is not readable should be rewritten, not "improved" with comments. Adding comments to bad code is like spraying perfume on a turd.
I also believe that even when code is not very self-documenting, programmers should still read it. I hate to say it, but whenever I hear someone complain that a codebase doesn't have enough comments, my gut reaction is to consider the speaker as lazy or unskilled. I've learned a lot by reading and re-writing hard-to-read code over the years, and people who avoid doing so are neglecting opportunities to improve their skills. I have a lot of respect for people who complain about poorly chosen identifiers, spaghetti structure, and other aspects of legacy code, but I have little sympathy for those who complain that reading code is just too hard. If you would rather read comments than code, please get out of the programming business.
But I'm not an extremist in my views. While I think a lot of code is overcommented, I don't claim that all comments are useless or harmful. Comments are good for the following purposes:
- Pointing out discrepancies between what external documents say the code should do and what it actually does. ("TODO" comments are an example of this.)
- Describing workarounds for bugs in the compiler, libraries, OS, etc.
- Doxygen/JavaDoc-style comments are good, as long as they don't make the code unreadable. If there are more comment lines than code lines, it would be better to maintain the documentation separately.
The following types of comments indicate problems:
- Comments that simply describe what the code is doing in plain English are useless. This is usually a sign that the code was written by a novice, or written to be read by novices. Whenever I see a comment like /* This is how we do a constructor in C++ */, I know the writer was learning a new language.
- "Summarizing" the behavior of the next few lines of code is not a good practice. If a few lines of code serve a purpose that can be summarized easily, those lines should be extracted out into a named function.
- Comments like /* Changed 2004/12/23 by RGF */ are useless. This is why we have version control systems. I guess some people just like to see their name in print.
- Comments that explain how a function used to work, before being changed, are completely irrelevant.
- Commented-out code is distracting. If you don't need it, delete it.
- Long paragraphs or essays that explain algorithms or configuration options or other complexities don't belong in the code. Such information belongs in external documentation.
- Big comment blocks in some standardized format for every single function are my biggest peeve. When I see these, I know a Style Nazi is lurking in our midst.
I agree with Raskin that external documentation is important, and it is best to write such documentation before writing the code. However, it is not clear to me what the link is between this idea and the idea that extensive comments within the code are a good thing. I like tools like Doxygen, and I think Literate Programming is pretty cool, but I don't see those as the same thing as "comments." Trying to put LP-style information into comments in a plain-old C++ file is just stupid. If you want LP, then you should really do LP.
I have strong opinions on this issue, but I try not to be a jerk about it. I work with smart people who put lots of comments in their code, and I don't complain. But I don't hesitate to delete comments that have little value.