Commenting code is easy to overdo. Learning when to comment is an important, often overlooked skill.

When I began developing, I was guilty of many of the sins of a learning developer. This included a copious amount of code commenting, driven by a lack of confidence in my future self to have any idea what my code was doing, let alone what I was intending it to do.

While constant commenting seemed like a reasonable way to go about explaining to future me and other coders what my code was doing, I was also coding under the assumption that comments are, at worst, noisy and superfluous. As it turned out, copious amounts of comments invariably become a burden to maintain, and so they did not stay maintained.

This is how I learned an important truth: Outdated comments are just lies. Without constant vigilance and upkeep, comments will get stale, rendering what was once thoughtful English describing the intent of a piece of code becomes falsehoods which only serve to confuse and deceive.

Another realization I came to from my early days of comment heavy code is that often they were really me attempting to explain what was actually bad code. I really like how Stack Overflow co-founder Jeff Atwood describes this problem:

“Junior developers rely on comments to tell the story when they should be relying on the code to tell the story. Comments are narrative asides; important in their own way, but in no way meant to replace plot, characterization, and setting.” https://blog.codinghorror.com/coding-without-comments/

As a junior developer I always found it very attractive to use comments to describe both the how and the why of a block of code, when both of these qualities can be explained through code alone most of the time. Without even realizing it I was using comments as a crutch for explaining what should have been explained in the code. Robert C. Martin in his seminal work Clean Code also describes good code in literary terms:

“Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer’s intent but rather is full of crisp abstractions and straightforward lines of control.”

Indeed, Martin declares that the only “proper use of comments is to compensate for our failure to express ourselves in code.” By taking great care with how we name our variables, classes, and functions, we are almost always able to express ourselves without comments. If you feel the need to add a comment to explain what your function is doing, consider renaming the function to describe what it is doing instead. Take the following excerpt from a controller running our rent calculator on forrent.com:

While this is a small, innocuous piece of commented code, perhaps it could be refactored to not need any comments?

The above code is now more verbose, but the need for a comment disappears once magic numbers are labeled (0.15) and functions are named after what they do. Depending on the context percentOfIncome might serve just as well as the longer percentOfIncomeUsedForRent ; regardless, the onus is now on expressing ourselves with code instead of lazily commenting. What happens if the percent of income for low rent is later determined by the business to be 12% instead of 15%? In the original version both the comment and the code will need to be updated to reflect the change. If the developer implementing the change to the percentage does not also update the comment, it will become a lie to future developers as to what the code is doing. Refactoring the above code with the goal of removing comments has now actually improved the reusability of the Math.round() call. Now the functions for midRent and highRent can also use caluclateMonthlyRent instead of repeating the code for calculating monthly rent 3 times.

While this refactor may seem overkill in an isolated context, the value of explaining both the how and why with the code itself cannot be overstated. The more comments your code has, the more likely future you and other developers will skim over comments all together, further increasing the chances out dated information is propagated as documentation.

There are always going to be certain cases where comments are necessary. Some things in our code simply cannot explain themselves with code alone. But the next time you feel a need to add a comment to your code, ask yourself if the same comment could be expressed in code only. If the answer is yes, do yourself, your future self, and your fellow developers a favor. Live by the words of author Brian Kernighan in The Elements of Programming Style, “Don’t comment bad code — rewrite it.”

If you’re interested in learning how to turn comments into better code, check out my follow up article Refactoring Comments into Better Code.