Dan is the founder of Rectangular Software, an independent UK software company that provides development services and builds its own mobile and web applications. Dan has over a decade of experience in the software industry, building a wide variety of systems including casino, poker and spread-betting platforms, mobile applications, e-commerce websites, and network security software. His other programming interests include artificial intelligence, particularly evolutionary computation, and functional programming in Haskell. He has authored, or contributed to, a number of open source Java projects. Dan has posted 34 posts at DZone. You can read more from them at their website. View Full User Profile

No, Your Code Is Not So Great That It Doesn’t Need Comments

08.07.2008
| 9125 views |
  • submit to reddit

Code-commenting is so basic and so universal that every programmer, regardless of the language that they practise, thinks that they know all there is to know and that their way is the only sensible approach (I am no different in this respect). I guess that’s why there are so many blog postings offering advice on commenting (you can add this one to the list).

Even the elite of programmer bloggers are having their say. Steve Yegge covered it and, more recently, so did Jeff Attwood. Jeff’s basic advice, that you wouldn’t need so many comments if you wrote the code to be more self-explanatory, is sound but the idea that we should be aiming for some kind of perfect code that has no need for any comments is dangerous.

It’s not a sensible goal for beginners and inexperienced developers. Tell them that they should write good code without any comments and they will deliver on the second part but struggle with the first. Even among experienced developers, assuming for a moment that it is possible to write perfect code that doesn’t require comments, there will be far fewer who are capable of this than there are who think that they are.

The other arguments against commenting are even weaker in my opinion. Yes, poor comments are …well… poor. So don’t write poor comments, write good ones. And yes, if comments become out-of-sync with the code then they are not helpful. So don’t let the comments become out-of-sync, they are part of your code and should be maintained/refactored along with the code itself.

I don’t believe that I’ve read a piece of code and thought “wow, this has far too many comments”. Unfortunately, I’ve had the opposite reaction all too often. I don’t for one moment believe that it is possible to write quality code without any comments. Take Jeff’s own example:

Here’s some code with no comments whatsoever:

r = n / 2;
while ( abs( r - (n/r) ) > t ) {
    r = 0.5 * ( r + (n/r) );
}
System.out.println( "r = " + r );
Any idea what that bit of code does? It’s perfectly readable, but what the heck does it do?

Let’s add a comment.

// square root of n with Newton-Raphson approximation
r = n / 2;
while ( abs( r - (n/r) ) > t ) {
    r = 0.5 * ( r + (n/r) );
}
System.out.println( "r = " + r );
That must be what I was getting at, right? Some sort of pleasant, middle-of-the-road compromise between the two polar extremes of no comments whatsoever and carefully formatted epic poems every second line of code?

Not exactly. Rather than add a comment, I’d refactor to this:

private double SquareRootApproximation(n) {
    r = n / 2;
    while ( abs( r - (n/r) ) > t ) {
        r = 0.5 * ( r + (n/r) );
    }
    return r;
}
System.out.println( "r = " + SquareRootApproximation(r) );

I haven’t added a single comment, and yet this mysterious bit of code is now perfectly understandable.

Sorry Jeff, but that’s not “perfectly understandable”. I agree with extracting the square root code into a separate method with an appropriate name, but your second version (the one with the comment) was more informative since it mentioned which algorithm you were using (in your version, the maintainer is going to have to figure that out for themselves). Also, we’re still left with at least two poorly-named variables. We can forgive the use of n for the parameter since that’s kind of a convention but what the hell are r and t?

In my opinion, this is better:

/**
 * Approximate the square root of n, to within the specified tolerance,
 * using the Newton-Raphson method.
 */
private double approximateSquareRoot(double n, double tolerance)
{
    double root = n / 2;
    while (abs(root - (n / root)) > tolerance)
    {
        root = 0.5 * (root + (n / root));
    }
    return root;
}
Alternatively, if you don’t like the verbose comment at the top, you could either rename the method to something like newtonRaphsonSquareRoot (if you are happy for the method name to be tied to the implementation) or put an inline comment in the body explaining that this is the Newton-Raphson method. Any of the three variations will communicate useful extra information to the maintenance programmer, who can then Google “Newton-Raphson” if they want to find out more about it. Remember that code is written only once but read many times. It should be tailored for the reader rather than the writer.

This is all very well, but we’re still lacking some information. Why the hell is Jeff calculating square roots in this way? Why is he not using the library function? Is it because he doesn’t like the answers it gives him? Is it for performance? Who knows?

Well-written code will often answer the “what?” and “how?” questions with few or no comments, but you often also need to answer the “why?” question too. Avi Pilosof covers this in his response to Jeff’s post. Avi argues that rather than comment the code, you should comment the business justification for writing the code that way. This may mean inserting reference to particular requirements or issue reports.

So yes, favour code that is self-explanatory, but I don’t believe that you can always achieve the necessary clarity without a few well-placed comments to aid understanding. Code that is obvious to the author today is rarely obvious to the maintainer next year (or even to the author next month).

And if you still really believe that your code does not need any comments, then I never have to maintain your code.

From http://blog.uncommons.org/

Published at DZone with permission of its author, Dan Dyer.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Fabrizio Giudici replied on Thu, 2008/08/07 - 7:32am

I second you opinion, and I'm adding some points. One of the points that bloggers or top programmers / designers / methodologists miss is their assumption that all the other people in the world have got their skills (this applies not only to commenting code, but to the whole process). I mean, my experience is that I write / advice about writing code for others, and these "others" range from teams which are very experienced in Java to others will scarse experience; I'm also in maintainance mode for some projects whose owner company has _no_ experience in Java and won't ever have, since its focus is elsewhere. It is not unlikely that sooner or later rookies will have to put their hands on the code, not necessarily with a senior supervising (we can discuss about how but is this practice, and it's bad indeed, but this is how the world goes on) and I feel as I have to make sure that the code is comprehensible also by this kind of people.

Add to that that I often use my open source projects as pedagogic material (teaching people with a project from the real world is much more interesting that simple and small lab projects, where it's too easy to have everything fit and working) and you understand the need for some extra comments.

Eyal Golan replied on Thu, 2008/08/07 - 8:44am

Well, I do agree with your point of view, but have two comments.

1. As for me, when I write code, I always try it to be self-explanatory. I try to write it, so the next developer, in a year from now, could understand it WITHOUT comments. Only then, I add the comments. I find that this way makes my code much better.

What  I am trying to point out is, that for me, thinking without comments makes my code much better.

2. As for the 'comment the how' ( ... using the Newton-Raphson method)  - Isn't it always suggested that one shoud write the 'what' in a comment, and not how?

P.S.

I do write comments :)

Kevin Conaway replied on Thu, 2008/08/07 - 9:48am

Yes, poor comments are …well… poor. So don’t write poor comments, write good ones. And yes, if comments become out-of-sync with the code then they are not helpful. So don’t let the comments become out-of-sync, they are part of your code and should be maintained/refactored along with the code itself.

I've reworded your argument against not writing comments:

It’s not a sensible goal for beginners and inexperienced developers. What constitutes a good comment? Writing short, correct and informative English is hard. Even among experienced developers, assuming for a moment that it is possible to write good comments, there will be far fewer who are capable of this than there are who think that they are.

 I don't think you can say "Write good comments!" and good comments will magically appear.  Furthermore, you're now placing an additional burden on future maintainers (some of which will be lazier than you) who must now update the code accurately as well as the comments.

Ronald Miura replied on Thu, 2008/08/07 - 10:00am in response to:

I agree with Eyal. Focusing in comments, you end up not thinking enough on creating good code, relying on the comments for clarity. For example, is it better to declare a 'r' variable and write a comment saying '//radius', or just name it 'radius'? This is a pretty silly example, but it applies to all levels (method and class names), and you end up having lots of 'execute()' methods and '*Helper' or '*Utils' classes.

But, I also agree that the HOW should be documented, too, but only when it's complicated (which is the case of using any mathematical algorithm), and you're able to describe it 'abstractly' (like, '//using the Newton-Raphson method'), not describing the algorithm itself, like

//iterate on list
for (Item item:list)
//sum item.value to total
   total += item.value;
//returns total
return total;

I've seen this. Many times.

Cristian Vasile... replied on Thu, 2008/08/07 - 10:16am in response to:

This is exactly how I would do it. Of course we need comments. But a comment used where renaming an identifier would have been enough is in fact harmful and WILL make the code less readable. The same goes for adding comments for obvious stuff (like standard idioms).

We need comments to explain the stuff that is not obvious.

Write code so that a guy having at least one year experience will understand it.
Add comments where you think he will start scratching his head.

Done. Now you have the exact amount of needed comments. No more, no less.

Anshul Bajpai replied on Thu, 2008/08/07 - 2:48pm

We dont write code so that machine can understand it..we write code so that humans can understand it. This particular algorithm is a special case where one can mention the name of algorithm in comments..otherwise I never feel commenting my code and whenever I encounter a code which is full of comments, I immediately refactor it nd get rid of comments. And if the development team is working in isolation from each other then I think they need comments beacause then code reviews are lesser and code sharing is also less. So then developers need comments to explain what messy code they hve written.

Alex(JAlexoid) ... replied on Thu, 2008/08/07 - 4:08pm

Comment and annotate code as if your code will soon be maintained by a homicidal maniac!

Onur Ersen replied on Fri, 2008/08/08 - 1:37am

Commenting code and methods etc is something good as all we
agree but unnecessary comments really spoil beauty of functional code.

Besides simple things commented some people use big code block titles (which i really don't like) like those illuminated signs of casinos in Las Vegas :)

/ ******************************************************************
******************UNNECESSARY CODE BLOCK TITLE**********
********************************************************************
********************************************************************/

Dapeng Liu replied on Fri, 2008/08/08 - 2:42am

i would appreciate it more if the comments includes things like "what are the common mistakes"

since lib producers tend to rely on some assumptions in order to keep their codes simple 

 

Alex(JAlexoid) ... replied on Fri, 2008/08/08 - 5:35am

Things I found in comments were funny or irritating:
a) Commenting the obvious

/**
* This is a setter for property
*/
public void setName(String name){
this.name = name;
}

We get it already! Java code is FULL of getters and setters.
IMHO, a better way is to comment the field itself:

 

/**
* Country code according to ISO 3166-1 alpha-3 standard:
* USA, GBR etc.
*/
private String code;

public void setCode(String code){
this.code= code;
}


b) Lies in comments!
I know it's difficult to change the comment when you are changing the logic...

// We do not cancel for empty orders
...
if(isOrderEmpty(orderData)){
orderData.setStatus("cancelled");
...
return;
} else {
...
}

c) Crazy assumptions

String name = null; 
// NPE is not a problem
name.substring(...)

 THis caused application to crash!

d) Inexpereiced developer, told to comment

if(data.isFlag() == false) // Check if flag is true

 

These were real code samples! I mean nothing imagined.

replied on Fri, 2008/08/08 - 6:14am

My attitude normally is that if you don't understand a piece of code without any comments, then you shouldn't touch it! I've been mislead by left over comments enough to not trust them. On the other hand I normally comment classes and methods, but rarely code blocks within methods (only if there is something tricky done).

Slava Imeshev replied on Fri, 2008/08/08 - 5:20pm

Dan,

I agree. While it is possible that comments do not match the code exactly, no code can provide an overview of what the code is doing or supposed to do.

Without comments one would have to read the whole [code] passage to understand it. Those thinking that a couple of words method name can provide an overview that is informative enough are delusional or have never dealt with the horror of uncommented code.

Regards,

Slava Imeshev

Cacheonix: Clustered Java Cache 

Fabrizio Giudici replied on Sat, 2008/08/09 - 1:39am

I don't understand the objection that comments could not be updated as the code evolve. It's a programmer responsibility to update them, as well as for tests. Unless you do TDD (in which case tests are updated by definition), I don't think that test code updates automatically as code evolves. Which BTW is another of the very good points about TDD, but not everybody does TDD.

*** edited to add

What I mean is that in any case the programmer has to keep other artifacts updated to the code; if he doesn't he's bad, and not only for the comments.

Anshul Bajpai replied on Sat, 2008/08/09 - 4:49am

@Slava Imeshev

Well the method becomes horrible if the method is doing more than one thing it is supposed to do (violating the Single Responsibility Principle) and therefore one will need to comment the code. If the method is big then there is define chance that the small methods can be extracted out of that big methods and code becomes self explanatory. I believe the code itself should speak out what it is doing without giving stress to developers.

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.