Code comments: A quick guide on when (and when not) to use them
- select the contributor at the end of the page -
Comments vs. time
Suppose that we have a reasonably large code base which was built and deployed to production over the span of several months. Classes, methods and fields have all been properly commented. Maybe it looks something like this:
class User
{
...
/// <summary>
/// Gets the tax-paying region for the user based on
/// the user's residence address.
/// </summary>
/// <returns>Tax region for this user.</returns>
public TaxRegion GetTaxRegion()
{
Region homeRegion = RegionCodes.Find(this.homeRegionCode);
TaxRegion taxRegion = TaxRegion.FromRegion(homeRegion);
return taxRegion;
}
}
This piece of code returns an object representing the user's tax region. Tax regions can uniquely be determined from the region in which the user lives. And that's precisely what the comment says. Now, try to imagine a situation in which this method must support nonresidents who still have to pay tax. Legislator has proposed a special tax region just for that purpose, so here is the modified method:
class User
{
...
/// <summary>
/// Gets the tax-paying region for the user based on
/// the user's residence address.
/// </summary>
/// <returns>Tax region for this user.</returns>
public ITaxRegion GetTaxRegion()
{
if (this.IsNonresident)
return new NonresidentTaxRegion();
Region homeRegion = RegionCodes.Find(this.homeRegionCode);
TaxRegion taxRegion = TaxRegion.FromRegion(homeRegion);
return taxRegion;
}
}
Notice any problems? The first red flag here is that the old comment remained intact. It still states that the tax region is determined from the residence address, but this claim is no longer true in all cases. When developers forget to fix the comment code (after it's been altered), the result is confusion. This isn't so much a question of whether we want to let the comments rot or we want them shine. It's just one of the artifacts of long-running projects to have a certain percentage of rotten comments. And once that percentage grows, developers tend to stop relying on comments -- if they ever relied on them in the first place.
Bottom line: Code comments do not stand the passage of time.
Comments vs. bugs
Of course, we can say that the comment must be changed whenever its corresponding code is modified, full stop. But try to say the same thing on Friday evening around 8 p.m. as developers struggle to procure a hotfix to the production. Chances are no one will even look at the comment, let alone bother writing it over. On Monday morning, the general response will be something like, "Yeah, we had that critical on Friday, but we're okay now.”
Bottom line: Code comments are the first victims of bug-fixing.
Comments vs. refactoring
Recently I had a case of a dozen classes that needed to be refactored. They were mixing two responsibilities in an awkward way. The decision was to split these two responsibilities into separate classes. Parts of the code would go into one namespace, while other parts remained as they were. Some classes disappeared completely, and a few more new classes appeared. A couple of new classes were added to coordinate the others.
The refactoring took a day and it went well, thanks to helpful unit tests. The whole process consisted of many small steps; change the code and its corresponding tests, when all green commit and step to the next piece. All operations were conducted using integrated refactoring tool, no manual refactoring. One important aspect of this task was that classes had no comments. Otherwise, all comments would've needed to be rewritten manually, requiring a tremendous amount of work (the task could have taken a day and a half to complete).
Bottom line: Code comments do not help refactoring, but make it more difficult.
Comments vs. documentation
Years ago I relied on automated converters, which can build API documentation from XML comments in .NET or Javadoc comments in Java. This practice, however, turned out to be of low value. For one, there were rotting comments in the code base. One way to find them was to send out the documentation and then listen for cries of help (for every error in the source comment, a user will surely call support about it). Additionally, I always had to re-package the document into the company's own format. That is (even today) tedious, manual work. Eventually, I found it much easier to write or refresh the required documents occasionally, completely by hand, and exclusively on demand. That really pays off.
On a related note, I've had several opportunities to receive such API documents. In these instances, I relied on the "show me the code,” or "show me the public interface" maxim. I can trust the code more than the document, for sure.
Bottom line: Code comments do not help build documentation faster.
Comments vs. code
The previous statement is a strong one; I trust code more than documents. Code executes while documents tell the tale of how it might unfold. When you have to fix the bug, would you read the document to pinpoint the problem? No. Instead, you'd read the code and search for the error. Programmers are trained to ignore the code comments entirely when simulating execution errors in their heads. It only pays to read comments at the very line where we suspect the bug is hiding. Basically, that comment would be the only one worth writing.
And let's not forget the issue of comments versus language; sometimes code doesn't tell the full story. When this is the case, it's not only useful to write comments in code, but it should be mandatory. If everything else fails, you can even write a separate document, with graphs and images, and refer to it in the code. The rule of thumb here is that code comments are useful when a programming language doesn't communicate intention well.
Bottom line: Code comments are of little help when trying to understand code execution.
Takeaway
You can put comments against all sorts of things to see what happens. But in almost all cases you'll conclude that code comments are just standing in the way. After years of experience, I can freely say that there are only a few legitimate situations that call for code comments, and those are the situations in which programming language is not the proper tool to pass the information.
This happens when we work on a problem from a specific domain, such as graphical representations, electric circuits, fluid dynamics, economy and financials, etc. Programming languages simply don't reflect those domains well, and corresponding source code could look opaque and hard to understand; make sure to put a line or two of comment next to such code. And never use comments around code that clearly conveys what it does.