FIXME: An Underrated Comment
Previously: Why Comment Code?
Sometimes you see comments in large or old code bases that say things like: “Optimised code, do not simplify“ or “Reference implementation, do not optimise“ or “Do not attempt the obvious bug fix“ or “We tried that and it did not work, so here is what we did instead”. Or you see comments that say “HACK:“ or “FIXME:“. Another fun one: “The above is equivalent to the following naive implementation.“
These comments all have one thing in common: You rarely see them in textbooks, and if you hand them in in your university homework, the tutors who grade your submission will know exactly what to deduct points for. Usually, homework problems are constructed with a specific solution in mind, so these kinds of comments are not needed.
If you turn in an assignment with a “HACK:” comment, you forsake your chance to get a perfect score, which you might have gotten if you kept your mouth shut. Similarly, some open source projects have automatic linters that do not accept patches and pull requests which contain “TODO:” and “FIXME:” comments. Personally, I think that’s terrible, not because you deduct points in homework assignments for honesty, but because you teach students to never write such comments. In the real world, a “FIXME:” comment can be very useful. Sure, outstanding tasks should preferably be tracked on the project’s bug tracker, not just in the source code, but if there is a problem in the source code that is known to the developers and clearly localised to a specific line in a specific file, there is no good reason not to comment that the code following the comment is broken in a known and predictable way. Closing the bug in the bug tracker won’t magically fix the code, but when somebody actually touches the code to fix the bug, that comment is right there to be deleted. A good compromise could be commenting the bug tracker ID in the source code. A perfect-world solution would be to just fix all the FIXMEs and do all the TODOs.
If you just comment what the code is supposed to do, not what it actually does, you may confuse both downstream users and future maintainers. Preventing developers from writing “FIXME:“ comments is a bit like preventing them from pushing code with failing test cases. It discourages people from writing test cases that actually find failures.
The “don’t even try“ kind of comment is the opposite of that - instead of warning the next developer of a potential problem, it asserts that there is nothing wrong with the code. It’s also frowned upon in educational contexts, because you are not supposed to write code that needs maintenance, or even code that looks like it does, but actually doesn’t. It’s much more dangerous if turns out to be wrong or obsolete.
But you know what’s really painful? When a new contributor looks at your open source project, and decides to refactor that one function to make it more readable - and then he gives up, because removing the goto statements, two out of seven total goto statements on the whole project, makes the code even more unreadable. Or he tries to simplify an unrolled, tight inner loop.
Like “TODO:“ and “FIXME:“ comments like these point to a deeper problem, but it sure is better to be honest about it than to sweep it under the rug. In an ideal world, you would have test cases and benchmarks to catch bugs introduced by overeager refactoring, as well as accidental de-optimisations. The biggest failure mode of these comments is establishing a zone of “code ownership“ or territoriality, discouraging others from improving or just understanding your code, maybe long after you left the project. If you tell future developers “do not touch“ or “you are not supposed to understand this“, then you better make sure that somebody in the project understands the code well enough to touch it.
At the end of the day, comments are there to help your fellow programmers to understand what they cannot understand from the code itself. That’s why you don’t comment “//increase x by one“.
On a higher level, comments can help your fellow programmers understand that the code does or does not look like it is supposed to, that your code does or does no do what it is supposed to do. From looking at the code alone, somebody might infer that a simple function does what the function name says, that it handles all the edge cases. By looking at the code alone, somebody might infer that a complicated function is a candidate for refactoring.
On order to communicate effectively, you should say with code what you can say with code, and use comments to say whatever important things are left unsaid.
Time to unlearn a bad habit from Introduction to Programming!