I’ll let you in on a little secret. The key to writing good comments is … (rolling the drums) … not writing them at all! Let me elaborate on that.
To me, there are two kinds of comments:
- The ones who appear right in the guts of a particular method.
- The ones who appear right above a particular method, mostly in the form of XML comments.
Code comments
I try to avoid these kind of comments at all times. Sure, there is a time and place for comments like these. But if I do feel the urge of writing a comment for clarifying a piece of code, then I turn back to the code, looking for a better and cleaner way of expressing my intent. If I’m just too stupid and can’t find a cleaner way for writing those particular lines of code, then and only then would I consider to put a comment in place (probably feeling bad and miserable for the rest of the day).
Writing a comment clutters the code. Besides that, a comment gets out-of-date sooner then Master Yoda can use his lightsaber. Most developers just don’t have the discipline for maintaining comments. It’s all about finding the best way to communicate with the future readers of the code. The best way is through the code itself, writing code comments as a miserable second.
XML comments
A few years ago (roughly 25 years on the IT calendar), when I stepped out of the C++ world into the .NET world, I found this tool called NDoc. Back then, this was one of the coolest tools in my tool bag. The entire world was telling me that writing comments was actually a good thing. So I did. I wrote XML comments for practically every method I’ve put out. Nothing could stop me.
Over the years however, I’ve come to my senses (it was just my time, it was just my time). Today, I use XML comments sparingly. The only time I ever use XML comments is for writing documentation for public API’s that are going to be used by other developers in other teams. Even then I feel bad about it because I almost know for certain that nobody is going to read them.
Again, I pull the card of maintainability here. The code changes, but the XML comments mostly never do. I’ve also seen too many of these:
/// <summary> /// The first name. /// </summary> public String FirstName { get { return _firstName; } } /// <summary> /// The first name. /// </summary> public String LastName { get { return _lastName; } } /// <summary> /// The first name. /// </summary> public String Company { get { return _company; } }
See what I mean. Notice the clarifying nature of the comments? Notice the implementation of copy-paste driven development?
So kids, stay away from comments. If you care about what you do as a professional developer, then you try to communicate using lines of beautiful code.
Ciao
I share your enthusiasm for self-documenting code and your distaste for bad commenting practices. In particular I can’t stand the cut and paste bloat most developers seem to use for their XML comments.
On the other hand, I think in-line comments are essential for clarifying certain decisions in your code. One of the underlying technologies/frameworks you are using may require that things be done in a non-obvious way and comments can serve as warnings against going down those other roads when other developers (or even the original developer) think they spot a better way to do it later on. Advocating that a developer seek a cleaner solution every time they come up against one of these situations is not helpful. At least it is unhelpful assuming the developer is smart enough to know the difference between an ugly hack and a necessity.
I agree with you wholeheartedly. One of the things one of my CS instructors taught me was “Comments Lie!” … and your examples above are perfect proof of that. The code changes and evolves and the comments rarely do…
Re: XML comments, the low point for me was the introduction of tools like GhostDoc that generate XML comments. I still remember the day that tooltip telling me that NickName stood for “the name of the nick”.
Hey, if the XML comment is so obvious that a tool can generate it, it’s probably obvious enough to be even needed.
Comments imply “this came from someone’s brain”
I don’t think comments are completely evil, only what we write in the comments. I believe there are two valid reasons to write comments. The first you touched on, XML comments that will be use with documentation tools like JavaDocs. The second is “why” you are doing something, and only when it may not be obvious to a future programmer working on the code. The biggest use of this is when I was forced to use a particular approach to a problem that, on the surface, didn’t seem like the best approach but because of hidden issues (or a business rule) I was forced to do it this way.
I believe that we should assume that the target audiance will be another programmer. As such, a comment called “the First name” for a Property called “Firstname” is stupid. I agree that if you have to comment “what” you are doing, then you should re-write your code.
That being said, I have worked for Project Managers that wanted it commented enough so they could understand it. One even had a rule of a comment every 5 lines of code. :-S
When I find myself compelled to write a comment in the middle of a method, I’ll usually stop myself, and pull that block of code out into a private method. There are a few advantages to this: (a) any future maintainers of the calling method don’t have figure out what that tangled knot of code is doing; and (b) it’s easy later on to refactor or rewrite the private method if a better solution presents itself. In general, if you feel the need to explain yourself via comments, the code you have written is probably not going to be understood by future developers (including yourself).
[beginSarcasm]
I guess if no one else is ever going to use your code, or if they will always have the sourcecode so they can figure out what you mean, then by all means, do NOT comment, I mean, really, I have gobs of time to read sourcecode and/or guess what your code does.
[/endSarcasm]
Take ASP.NET MVC. Great framework. ZERO comments(yet). If I wasn’t able to walk through the source code i’d never know what the expected outcome was supposed to be of many features. For example, a signature in the HtmlHelper class looks like this in the intellisense:
string Hidden(string name)
can anyone(who hasn’t already used the HtmlHelper, tell me what the does? clearly the name of the element will(should) be whatever value is in name, but what’s the id of the element going to be?
Here’s another one without a comment:
string TextBox(string name, object htmlAttributes)
What do you stick in htmlAttributes? Thankfully I consume enough caffeine and stay up late enough to read the source code and figure out what goes in there, but a simple little comment would have eliminated the need to read anything beyond the comment.
“The first name” as a comment is stupid, because it doesn’t give any useful information. However, comments like “Gets or Sets the First Name”, are important [to me] so i know, via intellisense, what’s readonly and what’s not before the compiler let’s me know.
I do agree, if the code speaks more than a comment could, leave the comment off. Superfluous comments that reiterate in psuedo code what the code does is always annoying. But if it’s a public API that someone else has to read, ask somebody else to look at it first for clarity before deciding the “no comment ever” direction.
Furthermore, could you imagine all of the .NET BCL without comments? Yikes. No thanks.
I thought I made it clear that XML comments are valuable for public API’s if and only if they are being maintained (maybe I have to work some more on my writing skills). ASP.NET MVC is definitely a public API.
I still don’t see the case for inline comments though. Like Keith mentioned, I’m more in favor of extracting a private method with a nice descriptive name than putting out a comment.
As I mentioned in my post: there are cases for inline comments, but I do find them rare as I mostly try to solve this with refactoring.
I’m a big fan of inline comments and I tend to be critical of code that does not contain any inline comments. That being said, inline comments should never be used as an excuse for indecipherable code. Here are my basic rules:
1. Any logic that is somewhat complex should be put in its own method with a very descriptive name. In addition to making the code more testable, inline comments may be able to be avoided.
2. Anything within the body of a method that is not obvious given the purpose of the routine should have a comment.
3. Anything that relies on non-obvious business rules or unusual usage of an API should be commented.
Even though I enjoy reading other people’s code, English is still my primary language, and compiling code in my head to determine it’s intent becomes annoying very quickly.
I think that XML comments are too important to be limited to a public scoping. While I love having SandCastle as part of my post-build process to generate my documentation, I am even a bigger fan in having Intellisense tips throughout the application.
For my team, verifying the validity of a comment in a changed section of code is part of the code review process. It really becomes second nature, and it is very easy to spot when the code has changed enough to be different from the comment provided. Beyond that, it is an indispensable reference tool for new developers to be able to hover over anything in the IDE and see the description, as opposed to jumping to definitions or running split windows.
Of course, it comes down to a little bit of personal preference and team buy-in, as well. The team, collectively, wants this level of functionality and understands the responsibility to make it valuable on an ongoing basis.
Beyond that, I am in complete agreement. When inline commenting becomes common practice, it is usually indicative of the need for refactoring. I try to limit my use of commenting to explicitly call out TODO items or to note why one approach was chosen over another.
If you’re working on code that is simple enough to write without inline comments then I don’t envy you. The most interesting code needs literally blocks of comments to indicate what’s happening, why things are being done, etc. They are used to explain why a particular approach was taken, and perhaps more important what other approaches were considered and why they were not taken; this simply cannot be done in code. Comments are particularly important in multi-threaded code to explain potential race conditions etc.
My assertion is that code without comments simply doesn’t work: http://gregbeech.com/blogs/tech/archive/2008/08/04/code-without-comments-is-code-that-doesn-t-work.aspx
I suggest using Ghost Doc http://www.roland-weigelt.de/ghostdoc/ This tool will auto generate comments for you for methods/properties based off the naming structure along with the parameters.
Combine this with Resharper http://www.jetbrains.com which will inform you when comments for methods have parameters that don’t match or don’t exist or do exist and shouldn’t.
These tools can easily lead to development with zero comment stagnation. I agree with you for in code comments they should only be used on very hacky solutions and for nothing else. Everything else that SHOULD be commented needs to be refactored into variables with proper names for what it is, to seperate methods or even entirely new classes to avoid the need for having to read anything other than the code itself.
@Chris: I’m a GhostDoc user for as long as I can remember. The tool is nice for micro-comment productivity, but if its output can be generated from the code itself, then what’s the point?
“…but if its output can be generated from the code itself, then what’s the point?”
@Jan: how is the output from Ghostdoc generated from the code itself?
What I was trying to say is that if the comments can be generated by a tool, then what is the point of writing comments then. If a tool can figure it out, then a human certainly will.