Writing better comments

Writing better comments

We are all familiar with some kind of concept of writing good code[1] and how extremely difficult it is to write in situations where deadlines exist (you don't have time to think things out. So naturally you cut corners and make compromises). Things get a bit more complicated when you realize that trying to figure out good code is like trying to decide what a good painting is - what you might think is the most elegant piece of art on the planet might be one of the most horrific things someone else has ever seen.

Regardless of what language you speak (verbally and programmatically) or tools you use, chances are you've come across code that looks like it belongs in the obfuscated C code contest hall of fame[1:1]. It's usually very hard to read, poorly documented and causes a huge spike in WTFs[1:2] per minute. This is bad code.

The truth of the matter is, the vast majority of us will probably never write good code. Holding your work to that standard while coding in corporate environment, battling unreasonable deadlines makes about as much sense as searching for big foot on the streets of downtown Manhattan[1:3]. What you can write on the other hand is code that, quite frankly, doesn't completely suck. This is decent code.

... most of us will almost never write good code ... What you can write on the other hand is code that doesn't completely suck

A common mistake is to confuse decent code with aggressively commented code. After all, that's what a lot of us were taught to do - "Comment every other line or so. Explain in detail what the code is doing, how it's doing it and what the result should ultimately be". As a result we get infuriatingly redundant comments like

int x = 5; // set x to 5 
int y = 2 * x; // calculate the value of 2 * x and store it in y 
int average = (x + y) /2; // compute the average          

Your code should be self documenting

Self-documenting code is code that pretty much explains itself. Kind of like how you were asked to show your work during math class in middle school; teachers require this because it is basically a step by step guide explains how you arrived at your solution. Self-documenting code works exactly the same way. The code shows you, in a clear fashion, how it works. You do this partly by selecting descriptive variable and method names. Selecting good variable and method names can be the difference between decent and bad code.

Consider the following example,

int d;                 // time measured in days
int roc;               // change that occurs over time

int[] rt;              // roots
rt = qRts(-1, 2, 3);   // calculate quadratic roots

Selecting good variable and method names can be the difference between decent and bad code.

The use of abbreviations only obfuscate the code. In the case of the first two variables d and roc there is no reasonable way of understanding at a glance what they are supposed to represent. d could easily be mistaken for delta or dimension. The comments become the only way of understanding anything that is going on and heaven help you if there are no comments. They are not self-documenting. More verbose variable and method names remove the need for comments.

int timeInDays;
int rateOfChange;

int[] quadraticRoots;
quadraticRoots = calculateQuadraticRoots(-1, 2, 3);

You might be tempted to make the case that less code means more efficiency. No. Compilers are pretty good now. Most compilers in use today do a lot of code optimization behind the scenes. This means that they try to optimize your code for performance and compactness[1:4].

Self-documenting and readable is not aimed at benefiting the compiler, it's for you and other programmers that may be tasked with maintaining your code in the future. Ideally you should write code as though comments don't exist in the first place.

Explain why, not how

So, code that doesn't suck is clear to anyone that reads it. What it can't make clear on the other hand usually not clear is why the code is there in the first place. Comments should explain why certain decisions were made which are not made obvious by reading though the code. For example,

* Math.pow is not used here 
* because it's slower than multiplication
public int calculateAreaOfSquare(int lengthOfSide){
    return lengthOfSide * lengthOfSide;

Comments should explain why certain decisions were made which are not immediately obvious...

It's painfully obvious to anyone what the method calculateAreaOfSquare is trying to accomplish. The method name states it's intention, the variable name states what the method needs and the "algorithm" is clear as day. However what may not be clear would be why the multiplication was used in place of Math.pow from the java standard library. This is where commenting actually becomes useful, by filling a need that the code, by itself cannot.

This comes in stark contrast to comments that pretty much just state the obvious

i++;        // add one to i

and comments that add absolutely no value to the code other than increase WTFs per min. This is evident in this code snippet shared with me by a colleague.

dout.write(dtmp);        // I can't remember why I put another signal here.
                         // but it should work...

Keep your comments up to date

Does this seem familiar? You've been working hard on a particular method. Provided useful comments as usual when all of a sudden, your deadline was moved up and your requirements have changed slightly. That's no problem, a quick adjustment to the code and, woo hoo! Home in time for dinner. Well. I hate to break it to you, but you forgot to adjust your comments as well. Now you have comments that is no longer in sync with your code. Anyone that reads them now has to decide whether to believe the code or the comments.

[Your comments] are effectively a contributing a part of your code base...

Your comments, when used correctly, are effectively a contributing a part of your code base and deserve no less the attention given to your code. Poorly maintained comments are a very easy way to create problems, introduce misunderstandings and have angry co-workers call you in the middle of the night.

Footnotes and references

  1. Hadi Brais goes into a lot of detail about how the Microsoft Visual C++ compiler optimizes code. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

Subscribe to Another Dev's Two Cents

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.