Skip to main content

What Can You See: A Guide (Rant) on Commenting

I occasionally find code examples online where the author, in their effort to fully communicate the breadth and detail of a proposition and solution, has commented almost every, or every single line of code.

I am not going to say that exhaustive commentary is universally opprobrious, but as sample code online, for my part, all I can do when I see this is rage close the tab and look elsewhere for examples to help me with my project. I will, however, propose that there is almost no use for the

# comment
code;
# comment
code;
...

format. The alternation is arresting to the reading of either code or commentary. The only way to get any comprehension out of this maximally irritating and interrupting layout is to slowly read each line sequentially from top to bottom and hope the author's flow of logic is perfect and simple enough to communicate the essential detail you're looking for without rereading. I suppose then this kind of commenting might make sense for beginners (to beginners?), but even then, I wouldn't expect a beginner to learn, or want to learn this way from 100+ lines of code (that is 50+ lines of comment and 50+ lines of code). One of many errors of presentation this style gives away without even reading the code (or the commentary) is that the author can't or doesn't know how to separate information on the structural and conceptual layers in the code. As a result, interspersed amongst all the comments telling you about how variables are getting initialized must go the fragmented discussion about what the code is trying to do. Everything is looked at from the perspective on the street. All you can see looking up are trees and tall buildings. There are cars driving by, but you don't know where they're coming or going, or why. You can't gauge the relative height of the buildings, or the architectural aesthetic of the trees. Civilization looks lovely and elegant from an airplane window. There is no need to agonize over street signs when you can clearly see how the roads connect. Exessive commentary would just distract the view and make you want to look away.

This reminds me of an astronomy presentation I attended a few years ago. The presenter was discussing his project's work of photographing the sky with an ultra high resolution camera. While I don't dismiss the importance of increased precision of scientific instruments, something about the approach seemed naive to me in the same way that commenting every line of code does. High precision comprehension or visibility should not set the attention to the little bits. Rather the increased resolution should feel more like a grid relaxation, as if the optics you're using to peer at the subject eventually, by refinement, itself becomes sufficiently imperceptible. Of the many wonders of nature is that much like a fractal, each scale presents a different structure. Think for a moment about photographing the sky with a multi-gigapixel camera. How far out from the earth in spacetime must you travel before each pixel contains an area larger than a galaxy? Are there galaxies visible to your camera that far out? What about the movement of the earth against an intergalactic background compared to the exposure time at that distance? If you wish to learn about a biological structure, like an ecosystem, or a plant, you don't invent an ecosystem- or plant-sized fine dicer, cut the subject into the tiniest pieces possible and then make a great deal of effort zooming in on your new collection of bits. The windowing function in this case forces such a bias that any phenomena observed must be of your own imposition.

Good commenting, like good programming, requires experience and discernment. If you really have so much to say about what your code is doing, consider a programming guide or notebook companion. Apply a rhetorical format that is appropriate for the topic. You would not discuss refinements you've made to a Fourier transform routine in the same way you would write down the shortcuts you took in a project due to business requirements. In the former case, you're complementing the code with exposition on the advantages and applicability of your enhancements vs a standard implementation. In the latter case, you're reminding the reader or yourself that a known substandard, but acceptable solution was adopted because of external constraints and that it needs to be replaced.

Most of the time effective commenting means adding comments sparingly. My rules for commenting I don't think are too much different from the standard wisdom and are slightly contradictory in their separate goals:

  1. Focus the commentary on what the code is trying to do and what deviations you may have made if any from a more conventional approach, e.g. did you have to workaround an upstream bug? Your reader already knows how source code works, so don't waste effort on describing how an if statement works. Do spend effort rephrasing an irreducible compound boolean expression in more colloquial language.
  2. Only write a comment if the block of code itself cannot summarize on its own what it is doing. Code blocks that cannot express what they are doing have limited maintainability. Sometimes this cannot be avoided if you're using an arcane language or are writing a performance sensitive or resource constrained application.
  3. If you need to comment one section of code, try to comment the other sections at a similar level to aid the reader in how the code progresses from top to bottom.
  4. Try to keep comments at the same level both indentation-wise and concept-wise. If you find that you need to mix more than a few lower- or higher-level comments in, then consider this to be a sign that your code itself spans too many structural layers and needs to be refactored such that the code block/namespace/module/class/object/function/expression in question has a well-defined scope and a more singular narrative of commentary.
  5. If your comment on one section of code is much longer than the others, or you find that you can't clearly and succinctly express what it is doing, consider this a sign that that section might need to be refactored such that its purpose is less fraught and more singular. (The reader (of this blog) is invited to think a moment at this point about Euclid's postulates and what wonderful things happened to geometry when the parallel postulate was finally resolved into a triplet state.) Cleverness is its own reward and almost never brings additional value. Code that is not maintainable is only disposable.