But…… Commenting algorithms and APIs is not. If you’re writing good code, the code comments itself. If you look at some code and can’t tell what it is doing by reading the code, then chances are you’ve been doing a piss-poor job of some basic coding best practices, like naming variables based on what they are, functions by what they do and classes by their responsibility. When you write code you should strive to write code that comments itself. Once you realize that code can be self-commenting, you realize that there are some cases where self-commenting code does not give you the full picture. That is why I always advocate the commenting of APIs and algorithms and de-emphasize the importance of commenting the code itself.
An important question is where does the code end and the algorithm begin? Generally speaking it will be obvious. If you created a bunch of code without really thinking about what you were implementing, chances are you didn’t need to comment it (for example, displaying a text field, or processing damage incurred by a projectile). The names of the functions and variables themselves should make it abundantly clear what exactly is going on. If it is not, then you need to make sure you start at square one, and review your coding conventions. Smart coding conventions will do 50% of the work when it comes to making code self-documenting. Experience and intelligence will do 45% and the rest is left up to luck.
You’ve determined that a complex solution is necessary (are you really really sure it is necessary?) and that you might forget why you’ve implemented things a particular way. Chances are you either had to open google or a notebook to figure out some of the concepts and strategies necessary in the implementation of this particular feature. It’s pretty safe to say we are squarely in algorithm territory. That doesn’t necessarily mean we need to go willy nilly with our commenting just yet. Some algorithms might have complex concepts but very simple implementations. In these instances, we’re probably safe documenting the concepts behind the algorithms and why a particular implementation was chosen, but we’re still not commenting every second line of code. This high-level overview of the functionality of the code will be far more valuable than a play-by-play account of the individual pieces.
The other place where commenting is obviously necessary is when you are developing an API that other coders will be accessing. Because of the relative complexity and scope that an API generally implies (dozens of source files, thousands and thousands of lines of code), it makes sense to provide clear and concise instructions on how to interact with your architecture. The same principles still apply, though. Well-written smart APIs with limited commenting is inherently easier to learn and integrate than a messy API with full massive documentation.
In some instances commenting code is absolutely necessary to the maintainability of your code, but far more often you’re using commenting as a crutch to get away with writing bad code. Write smart, readable code. Code doesn’t get out of date. Code is checked by the compiler. Comments cannot be automatically synchronized with the code it references and it is not compiled and therefore not a candidate for automatic verification. Well-written code with very few comments is far more robust and maintainable than a haphazard implementation with in-depth commenting.
If you’re still not sure which category a particular comment falls into, consider the following questions:
- Is the comment paraphrasing code?
- Is your comment trying to clarify your implementation?
- If the code changes, is it possible that the comment will no longer apply?
If you answered “Yes” to any of the above, that’s probably a comment that needs to be eliminated, usually by rewriting your code to make the comment redundant (and therefore removable).
Writing self-documenting code is a skill that needs to be practiced. You’ll find the benefits are numerous, however, particularly when it becomes second nature.