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:
- Code should contain code (for the compiler). Compilers have no use for comments. Comments are docs and they should go somewhere else.
- Comments cost money to write and maintain
- If someone changes the code, but not the comment, then the comment is misleading and therefore, counter-productive
- 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.
– 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
//--- 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)
//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.
Now, I’d like to return to the primary arguments against using comments and debunk them:
- “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].
- “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.
- “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.
- “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.