Comment Only What the Code Cannot Say
It is often noted that the difference between theory and practice is greater in practice than it is in theory. This observation certainly applies to comments. In theory, the general idea of commenting code sounds like a worthy one. What could be more helpful than being helpful? In practice, however, comments often become a blight. As with any other form of writing, there is a skill to writing good comments; much of the skill is in knowing when not to write them.
When code is ill formed, compilers, interpreters, and other tools will be sure to object. If the code is in some way functionally incorrect, reviews, static analysis, tests, and day-to-day use in a production environment will flush most bugs out. But what about comments? In The Elements of Programming Style Kernighan and Plauger noted that "a comment is of zero (or negative) value if it is wrong." And yet such comments often litter a code base in a way that coding errors never could. They provide a constant source of distraction and misinformation, a subtle but constant drag on a programmer's thinking.
And what about comments that are not technically wrong, but add no value to the code? These qualify as waste. Comments that parrot the code offer nothing extra to the reader -- stating something once in code and once in natural language does not make it truer or more real. Version-related comments try to double up on the job of versioning tools, but are nowhere near as effective. There is an increase in source noise that has the side-effect of discouraging fine-grained versioning. Commented-out code is not executable code, so it has no effect for reader or runtime. It also becomes stale very quickly. Like version-related comments, commented-out code tries to address a versioning problem; versioning tools are already a more effective answer to that problem.
A prevalence of noisy comments and incorrect comments in a code base encourage programmers to ignore all comments, either by skipping past them or by taking active measures to hide them. Programmers are ingenious and will work around anything perceived to be damage: folding comments up; switching coloring scheme so that comments and the background are the same color; scripting to filter out comments. To save a code base from such misapplications of programmer ingenuity, comments should be treated as if they were code. Each comment should add some value for the reader, otherwise it should be removed or rewritten.
What then qualifies as value? Comments should say something code does not or cannot say. A comment explaining what a piece of code should already say is an invitation to change code structure or conventions so the code speaks for itself. Instead of compensating for poor method or class names, rename them. Instead of commenting sections in long functions, extract smaller functions whose names capture the former section's intent. Try to express as much as possible through code. Any shortfall between what you can express in code and what you would like to express becomes a candidate for commenting.