When to use comments (and when not to)

A few years ago, I was code-reviewing the work of a contractor.  It was the first time in my career that I saw code from an experienced developer with no comments.  None!  I was genuinely surprised by this and asked him what happened.  He told me that he always made a conscious effort to write his code in a manner that made it self-documenting and he believed that comments would end up being misleading to the next developer.

Um, okay, yes, I too expect all developers to write their code in a manner that makes it readable, but he lost me on the second half.  Why would comments be misleading? It turns out that he expected that my team would eventually update the code, but be too darn lazy to update the comments accurately.  I reassured him that this would never happen, because if anyone on my team changed code without updating the corresponding comments, I would kill them where they stood.  He thought about it for a second or two, and then he and I had some awkward laughter.

In the months since that discussion, I have come across several articles and blog posts on this topic.  It seems to be some recent trend in the programming community, to avoid commenting.  The argument against comments seems to be based on 4 primary points:

  1. Code should contain code (for the compiler).  Compilers have no use for comments.  Comments are docs and they should go somewhere else.
  2. Comments cost money to write and maintain
  3. If someone changes the code, but not the comment, then the comment is misleading and therefore, counter-productive
  4. Any programmer (worth a darn) can read and understand source code, unless the source code is poorly written.  So don’t write code poorly and you won’t need comments.

I recently read two contrasting articles about comments.  One In favor of comments, by Joe Kunk and another that implied that you shouldn’t comment your code, at all, by Peter Vogel.  Joe Kunk’s article was well-written and left me feeling more informed.  On the other hand, Peter Vogel (whom I greatly respect) wrote an article that was (pretty much) bananas.  In fact, a few weeks after he wrote it, Peter Vogel actually wrote an apologetic article which explained that he was not totally against comments after all.  Odd.

Both articles came to the conclusion that there are good reasons for adding comments to code and bad reasons.  After reading both, I found myself wishing that both authors had been less vague in that regard.  So I’d like to offer some examples of good and bad comments, as well as some reasons/conditions that each is good or bad.

Bad Comments

– Change history

// 2-16-2010 - Mike Smith - Somewhere in this code, there was a bug.
//     I changed several lines and now it is fixed.
// 2-17-2010 - Mike Smith - Um nope, there were still more bugs.  
//     Hopefully, this will fix it.  If not, I will add dozens of 
//     additional comments like this one.

This is the worst.  Don’t you have a SCM (Source Control Management system such-as TFS, SourceSafe, SVN, git or Mercurial)?  SCMs are designed to maintain a history of your code.  If you aren’t using one, then stop everything and start using one immediately!  Putting any dates or people’s names in code is just whacky.  It is like listening to a song and hearing a band mention their own name as one of the lyrics (*yeah, we were just another band out of Boston…*).  It makes my skin crawl.  It should be bleeped-out.  Oh and also, people who are new to using a SCM (or who are lazy) will lack the discipline to check-in their code with good descriptions.  It is okay to get totally gestapo on those people.  Tell them that I said so.  It is much better than putting horrible “change history” comments in code.

– Anything un-professional

//Yet another stupid database call

I’ve actually seen angry comments in code where a programmer expressed his frustration with the code or some work assignment.  Tell it to your shrink.  Un-constructive or unprofessional work (comments, var names, docs) is as dumb as complaining about your boss on FB.  Grow up.

– Dead code

//[ToDo: get this code working asap] if (!SpellCheck(product.Description)) break;

Again, your SCM keeps old code for you.  Once it has been checked-in, just strip-out any dead code (even if you intend to un-comment it someday).  You can always dig it up later.  You really should keep your ToDo list somewhere else (TFS, GitHub, Outlook, written in pen on your arm, but not in your code).

– Comments for every line

//Connect to the DB
conn.Open(settings.DSN);
//Run the query
reader = cmd.ExecReader(sql, conn);
//Loop through the result set

Let’s not get carried away.  In school, I was taught to do this.  It is silly.  Even rookies are annoyed by it.  Maybe it is okay if you are making some training materials or posting your code to codeproject.com.  Then it might make sense.  Otherwise, don’t do that.  It makes it more difficult to see/find useful comments.  The important stuff gets lost in a sea of green noise.

– Obvious stuff

//Function: Get Account Balance for Account Number
// param: #1. accountNumber - the account number to look up
public single GetAccountBalanceForAccountNumber(int accountNumber)

You laugh, but I’ve seen silly stuff like this.  The function name and comment are nearly identical.  The only benefit to a comment like this is if you have a doc generator that scans your code and builds docs from the comments.  Also, if your company has standards that require a comment for every function, you might want to re-visit that policy and realistically evaluate the value of consistency vs. wastefulness.

– Comments that don’t say anything

Image
Example: These code check-in comments are meaningless and valueless.

 

Good Comments

– Sections

//--- Validation --------

Comments like “Declarations”, “Open DB Connection”, “Validate input” might seem silly and useless.  It only seems like they can be useful for training rookies. However, if you have ever read non-code (like books, newspapers, this blog post, etc), you will notice that the pages are often broken-up into sections, with headings like “Bad Comments”, “Good Comments”. (In this article, look to the left for bold text.  Do you see them?)  Those are weird little navigation points for your eyes/mind.  You can quickly skim through some code, and your eyes easily find the green text that says “calculations”. (demo: Real quick, I want you to skim up and find the comment, in green “Connect to the DB”. Pretty easy eh?)  This kind of comment is not a waste after all.  They don’t require any effort to maintain and your eyes are quickly trained to find or ignore green (commented) text.

– Complicated code – one word: RegEx().

//grab HTML tags
"<([A-Z][A-Z0-9]*)\b[^>]*>(.*?)</\1>"

Everyone agrees that regular expressions are painful.  The next developer will stare at that regex for an hour before he remembers what </\1> means or why the results are usually the same when you remove the owl eyes 0\/0.  Undoubtedly, your code would be more readable if you replaced every regex call with 20+ lines of code but clearly, your code is just more succinct with a regular expression.  So, be decent and put a comment in front of it, for goodness sake.

 

Ugly But Functional (you have a good excuse)

– Warnings/Apologies

//I used a DataReader here because the DataAdapter seems to choke 
//  on my query

I have pulled my hair out trying to solve weird quirks like this before.   After burning up a half day (or half week), I left the landmine there with a warning sign above it.  I pray that nobody ever removes the foreboding message unless they can defuse the mine.  If you have ever “been there”, you know that a comment is proper courtesy, at a minimum.  If not, then don’t touch it because you have no idea what you are doing.  Don’t blame me if you break the build or crash prod.

– Debug/Test settings

  -- Declare @CompanyID; Set @CompanyID=30;

If you’ve ever had to debug a Stored Proc that was 2500 lines long, you probably just winced and nodded your head.  Silly (rookie) elitists will tell you that you should refactor that SP into fifty smaller SPs, but you know that is crap.  Sometimes, you just have to do battle with Godzilla (metaphor for a huge, awful SP).  You will pepper lots of checkpoints and trace statements that will make it easier to unit-test portions of the SP.  After all of that work, you just have a feeling that you will be doing this next week/month again.  Murphy’s law is drooling over you like a hungry buzzard flying circles over your SP, waiting for it to die again.  If you leave your trace code (commented-out), then you will never have to touch the code again, but if you strip it out, you will be back in there tomorrow.

Invalid Reasoning

Now, I’d like to return to the primary arguments against using comments and debunk them:

  1. “Code should contain code (for the compiler).  Docs go somewhere else.”
    Keeping the code and documentation completely separated creates a new challenge: how will each one refer to the other?  Pointers?  It is much more difficult to keep these in synch without any comments.  Don’t get carried-away and embed all of your documentation into your code, but some “cliff-notes” will help.  Think about the weirdest/dumbest business rule that you’ve had to implement.  You can’t seriously believe that it is better without a comment or a hint about where to get more info.  Plus, it seems like [the further the code and docs are separated], [the further out-of-synch they will tend to be].
  2. “Comments cost money to write and maintain”
    Yes, of course.  Everything costs money to write and maintain.  When you compare the cost (time) of writing code and comments, it is nothing compared to the cost of testing and debugging.  Not to mention maintenance time/costs.  Anything that helps grease these is an excellent investment.  Does it honestly take you much more time to write, read, ignore, navigate-around or update comments?  Maybe your speed/efficiency would improve with a little more practice.
  3. “If someone changes the code, but not the comment, then the comment is misleading and therefore, counter-productive”
    Realistically, the behavior described here is simply sloppy and unprofessional.  Coding standards that encourage this kind of behavior are disgraceful.  You should be ashamed.  Every company really should have standards that encourage excellence and punish people who deliver incomplete or broken solutions.  If a developer delivers code with outdated/inaccurate comments, then I wouldn’t trust anything else from that developer.  Therefore, this might actually be an effective tripwire to detect such poor craftsmanship.  I’ve heard some people call this a “job smell”.  Meaning, something smells rotten around here.  Keep an eye out for people who don’t care enough to update comments and be wary of companies who encourage or even condone this kind of behavior.
  4. “Any programmer (worth a darn) can read and understand source code, unless the source code is poorly written.  So don’t write code poorly and you won’t need comments.”
    You must be dreaming.  Yes, of course, don’t write code poorly.  Does anybody write sloppy or hackish code as their first choice?  I suppose, if you don’t care, you might.  Decent, self-respecting people never do this voluntarily, but yet it happens sometimes.  I’d even go-so-far-as-to-say that sometimes it is unavoidable.  Also, keep in mind that different people have different opinions about what is “readable”.  Somebody’s “Hamlet” might look like Latin to me or mandarin, or British, etc. (You can have my pardon. No need to beg.)  Of course, you can always expect higher-quality code from higher-quality developers, but it also comes at a higher price tag.  If your employer isn’t all “free and loose” with the wallet, then you will have to deal with some cheaper code and cheaper code is going to need more comments.  Caveat emptor.

There were a few other reasons for avoiding comments, that I read about but didn’t deserve my initial acknowledgement.  Each of these just seemed silly:

  • Comments can’t be checked for accuracy by the compiler.
    Ha.  I had to laugh.  Hey there lab-partner, do you suppose that the compiler can check your business logic?  What?  No?  I didn’t think so.  So, are you going to strip-out your business logic or just assume that if it compiles, that it must be correct.  Hahaha.  Maybe you would be better off relying on your docs (and comments) a little more and even throw-in a few code-reviews, for good measure.
  • Developers don’t read comments.
    I was dumbfounded by this one.  It is like saying “I don’t drink water”. Okay, I’ll have to bury you by Friday, because people can’t live without H2O.  Oh, you only drink Mountain Dew?  So, is it anhydrous Mountain Dew or did you just contradict yourself?  If you are a developer and you don’t read comments, you should be fired and get a job working in a mine, or somewhere else where there is nothing to read.

I’ve even heard people falsely state that comments have a low (or negative) ROI.  That is untrue!  Studies have shown that comments actually are useful to developers.  So, if ROI is important to you, I’d suggest that you don’t skip the comments.

In the end, all of this is a matter of opinion.  It depends on the size and maturity of your company and your team.  Your best bet is to formally identify coding standards/conventions for your department regarding [when to comment] and [when not to comment].  Then, enforce your policy via code reviews (and SCM monitoring/auditing).  Be prepared to change your policy when it makes sense and identify exceptions to the rules, (and when the exceptions are okay).

And, if you EVER change a line of code without changing the corresponding comment, may you be stabbed in your mouse-hand with a SPDIF cable, banished to Detroit and sentenced to a 2-year maintenance project for a technology that doesn’t use comments.  Like BizTalk or SSRS with Oracle or something equally horrifying.

Advertisements

About Tim Golisch

I'm a geek. I do geeky things.
This entry was posted in Professionalism, Programming and tagged . Bookmark the permalink.

5 Responses to When to use comments (and when not to)

  1. myjavaprogramming says:

    Thanks for this post. I often struggle with the amount of comments I should write.

  2. greenblades says:

    An evocative topic which I feel you have presented in a balance way. I think the penultimate paragraph was a good summation or at least one about which I feel comfortable. I would agree with you “identify coding standards/conventions” is the way to go. Thanks for sharing your thoughts.

  3. Peter Vogel, Learning Tree says:

    Not a bad article and at least one of the justifications for comments is worth making: apologizing for bizarre code (though we should recognize that is an unusual case).

    The article does misrepresent the point about at least one objection to comments. The point about “the compiler doesn’t check your comments” is that that there is no way to determine if a comment is correct or up-to-date: unlike code, comments are immune to testing and (unlike code) an incorrect comment will not be caught by any software testing process. A good rule: When someone says something that you think is laughable, it often means that you’re missing their point.

    I always find it interesting that the defense of comments comes down to the belief that programmers can be expected to write useful comments but shouldn’t, for some reason, be expected to write readable code.

    (and, by the way, I never changed my mind and said that comments in code were a good thing: As I said in the original article, comments at the top of a method describing the relationship between inputs and outputs are often worth doing).

    • Tim Golisch says:

      Wow. First let me say Mr. Vogel, I feel greatly honored that you would comment on my blog. I wasn’t exaggerating when I said that I have the utmost respect for you and your writings. You are one of the giants in our community and I must confess that I strained to post any criticism of your work. The goal of my article was more to show examples, than to call-out someone as venerable as yourself. I certainly do appreciate your honest feedback. Thank you.

      Having said that, I respectfully disagree with only one point of your statement: “Comments are immune to testing … an incorrect comment will not be caught by any software testing process.”

      I have found it equally challenging to expect typical software testing methods to adequately test anything that does not have a user interface. Such things need to be tested via other methods.

      The technique that I use to ensure quality of code (and comments) is via code reviews. Like any other form of testing, code reviews yield consistent results, and ROI, if applied consistently and methodically.

      During code reviews (that I’ve attended), as a team goes over things, periodically they will identify blocks of code that are technically accurate, but are complicated enough that they take a little more time to understand than others. Nothing about it is unreadable, but during the brief timeline of our code reviews, they feel pressure to quickly read and understand the code. Some parts stand-out as being harder to read and understand than others. In contrast, when the team goes over some moderately commented code, they find it much quicker to pick up any of it. The whole process moves much quicker.

      From a simply emperical standpoint, these code review teams seem to observe the value of comments. After performing several code reviews, the concensus is even more firm. Comments save time, if they are designed well.

      During code reviews, we make a point to also check the quality and accuracy of the comments. If any of the comments fail review, we consider it to be a quality “smell” (as in, something smells bad here). When that happens, it usually is a strong indicator that we might be dealing with a developer who lacks attention-to-detail and might be producing shoddy results. The extra scrutiny usually pays-off too.

      If your process is designed to catch such rascals, then reviewing comments (and other docs) will be another test/indicator that you can use to sniff them out. If not, then the comments will simply be one more irritant.

      • Peter Vogel, Learning Tree says:

        As I said: a good column.

        My claim is simpler: code reviews should review the code (hence, the name). If the code is hard to read or understand–rewrite/refactor the code.

        But, having said all that, as you point out in your column, there are places where “in code” comments are unavoidable (and “method level” comments aren’t going to cut it). I suspect that I have fewer occasions than you do when I feel comments are necessary. You’ve pointed out one already: when the code looks dumb but avoids some “unobvious” problem that the programmer couldn’t resolve. At least one other example (which I knew about, ignored because I was dumb, and–fortunately for the column–a reader pointed out): sometimes we write ugly code in order to achieve some goal (usually faster response time) and end up having to explain it in comments. I think that these exceptions are few and far between. And, when you do write those comments, they’re really (to borrow a term from your column) an apology from the developer writing them to the “next programmer.”

        It’s always a pleasure to read someone who disagrees with me intelligently–glad I came across this (I was looking for something completely different: the beauty of search in action, I guess).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s