a companion discussion area for blog.codinghorror.com

Coding Without Comments


#61

Weirdly, your post started out making a very valid point (tell us why the code is doing what it is, not what it is doing) but then you proceeded to argue an entirely different point about why you should refactor your code to make it is more clear what it is doing.

So great, the new refactored code makes it clear that you’re doing a Newton-Raphson approximation to the square root. But I still don’t know WHY you’re calculating a square root, or WHY you chose the N-R method (efficiency, accuracy, something else?).

The important comment here would be something like:

// using the N-R algorithm as it typically converges quickly 
// to approximately the desired root. we don't need the exact
// value here because {reason} so this gives us better perf.

#62

Sorry for the double post :frowning: but here’s an example of what I mean. Here’s a method that removes a subscription in a catch block, taken from our real codebase. It is very obvious as to what it is doing, but do you know why?

this.Unsubscribe(subscription.Id);

Now does this comment help?

// if the operation was invalid when we know the cause must be an invalid workflow queue and/or the workflow
// not existing because the only other cause from the methods in the try block is that the workflow runtime
// is not started, and that can't be the case here as we just checked. as we'll never be able to deliver the
// result to a non-existent queue/workflow then we need to remove the subscription otherwise it will stay in
// the pending work queue for runtime services that persist their jobs and cause the service to enter an
// infinite loop processing work items that it can never complete
this.Unsubscribe(subscription.Id);

#63

As far as I understand the re-written code, it doesn’t work.

‘t’ is never declared.

Unless it’s a global? And I know someone as precious as this about a simple thing like comments wouldn’t go around advocating a global.


#64

I find I put one or two comments in as I am working on a couple of methods then when I refactor sometimes they become unnecessary. Once I have got to a stopping point like written a set of methods or a full class I will have a quick scan through adding in some more general comments about what a method does if it isn’t apparent in the methods name.

Don’t comment with pseudo code most programmers can read the actual code easily. A comment should be a sentence covering what a set of lines do so you can skip them when debugging if you know they work.


#65

My first thought on reading the post title was: comments are not to be messed with.

But after reading your and Sammy Larbi’s posts I took a look at my more recent code… and realized you guys are right. I still think complex code needs comments, but as you choose descriptive names for your methods the code should be self explanatory.

Posted an example of my own code on my blog: http://www.markvandenbergh.com/archives/21/no-more-comments-in-your-code/


#66

I’ve heard this before, and I consider it disingenuous. Only a relative few are able to read code as effectively as a code interpreter. I’ve worked with many developers over the last 20 years and I can’t think of a single individual who could do it perfectly.

What does this post really mean? Should everyone unable to read code as efficiently as the author go dig ditches for a living? The vast majority of coding is done by average developers who may need comments to help them along the way to comprehension.

This is especially true of maintenance development where coders are reading code which may be many years old and have numerous coding styles, with little or no documentation to follow as to the purpose of every function or feature.


#67

My response to Jeff’s post:

http://blog.uncommons.org/2008/07/25/no-your-code-is-not-so-great-that-it-doesnt-need-comments/


#68

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

Actually, no. I still have no idea what the hell that algorithm is and why it works. OTOH, // square root of n with Newton-Raphson approximation tells me all I need to know in order to be able to find more information about the algorithm, should I need it.


#69

Agree 100%. If you can’t tell what the code does without comments, the code isn’t done yet.


#70

Whats a comment? Whats documenting?

My 10 bits.

Comment as a prototype of the code, just to get my idea of the code out.

Replace the comments (not underneath) with the code, often being a meaningful method name.

Add comments to highlight any quirks, notes, methods used, reasoning why. e.g. Uses X method to do some awesome sh!t to the string, This code is sluggish, but I cant think of a better way, tried x,y,z.


#71

It’s funny how often I see people complaining about out of date comments then not fixing them.

Most of the comments make the code less readable argument is simply looking for an excuse not to have to explain what their own crappy code does when they often don’t understand it themselves.

Personally I have really wanted comments quite a few times just to judge the intelligence and intentions of the author. Did he know what he was doing when he added this apparently extraneous variable? Often you don’t find out that it was actually a key hack added at the end to support some business rule until you’re in the middle of removing it.

Any time you hit code that you don’t get within a few seconds, be it yours or someone elses, FIX IT. Either add comments (which has the benefit of virtually never breaking the code) or refactor the hell out of it until you have something understandable.

If you just leave it and work around it, letting the next guy start from scratch as well, you’re worse than the original author because you KNEW there was an issue.

Basically your code should read like a book when you are revisiting it (not when you are writing it and it’s fresh on your mind). There should never be a question as to why you are doing something.

As you pointed out, this can often be done by very small single purpose methods and classes that are appropriately named (Anyone that thinks that simply naming things well will do it is part of the problem though).

Honestly it’s a LOT more work to make readable code than to write a few readable comments, and I doubt a lot of programmers are even capable of writing readable code–then someone comes along and gives them the idea that using a 30 character method name for a 200 line method is going to absolve them of all responsibility.


#72

Comments are for anything unusual in my books.
Anything that isn’t immediately obvious or would look a bit wrong without a comment. This means that they describe either some form of hardware or architectural limitation, a fixed bug, some performance hi-jinks or a curious customer requirement.

Oh I also use them to explain to readers that i’ve considered certain code paths and am happy they do nothing.

if(blah)
{
blahblah
}
else if(blah)
{
blahblah
}
else
{
// do nothing
}

#73

Well, I partly agree… and then I disagree again. First of all

COMMENTS ARE GOOD!

Never think otherwise. Trying to avoid comments is a step into the wrong direction. It’s not about avoiding comments. It’s about getting your comments RIGHT™.

As other people pointed out, by choosing the right name for the function, you made clear, that this function calculates a square root. But you don’t tell people which method it uses and why you chose this method.

This gets me to the point:

  1. Don’t use comments to tell people what you are doing, unless it is very hard to see that by just looking at the code. Always assume that whoever will read your code is a good programmer and knows the language your code is written in quite well.

Most useless comment I have ever seen:

// Increase i by one
i++;

<sarcasm>Wow, thanks for the comment. Without it I had never guessed what happens there!</sarcasm>

If somebody needs a comment to know what i++ does, he shouldn’t be reading this code in the first place.

But your square root example is a good example where I would leave the comment, even if you chose the function name to be more obvious, the name does not reflect which method you use for calculating the square root. I had at least written that as

private double SquareRootApproximation(n) {
// Using Newton-Raphson approximation
...
  1. Always use comments to tell people WHY you are doing something.

The what might be obvious by just looking at the code, the why certainly never is. How can it be? The why exists only in your head. It’s a design decision you made while writing the code and maybe not even you yourself will know 3 years later why you made it that way and not any other way. So make sure the why is either always obvious (because it’s trivial) or add a comment that explains your design decision.

  1. Don’t over-comment.

I guess that was your main critics here and I totally agree with you. A lot of code has more comments than actually code. If that happens, something is wrong. It’s highly unlikely that 100 lines of code are so complicated, that they need 300 lines of comment to understand them.

If you really implemented something so ingenious, that you want to share your cleverness with the whole world, write a 50 pages PDF file, upload it somewhere on the web, add a two line comment to your code that contains a link to it. Who really cares for a long winded explanation of what this code does, why it is so cool, a proof that it really works, a performance comparison, and so on, can grab that PDF and read it. For the rest of us, just add a comment what the code does, why you decided to do it that way and that it is really great - we will believe you :wink:


#74

While I absolutely agree about properly factored code and good naming conventions, I think this conclusion is naive:

if your feel your code is too complex to understand without
comments, your code is probably just bad. Rewrite it until it
doesn’t need comments any more. If, at the end of that effort, you
still feel comments are necessary, then by all means, add comments.
Carefully.

It only works in simple systems where you, the singular developer, control the entire codebase, any you’re not interacting with any other systems. For instance, it works great for pure data-in/data-out algorithms.

Reasons for commenting usually have little to do with the quality of the code itself, but rather a limitation of the architecture you’re living in - for instance, the web.

When your application is spread across server and client code, UI code/resource bundles, CSS, etc, and depends on the quirks of HTTP caching, SQL performance characteristics, third party libraries, etc, you absolutely need comments to explain yourself.


#75

Whilst I don’t like essays as comments I still think adding that one line tidbit you’d added is useful.

// square root of n with Newton-Raphson approximation

Don’t get me wrong, I’d still probably stick it as some sort of static method in a utility class somewhere but I like to know a little about the logic being used, and I think it becomes more relevant with more complex examples.

As an example this week I was working on some code to calculate the distance between spherical coordinates (lat, long), for my purposes I decide that the haversine formula - with a rough error of 3m for every km - was suitable. To me putting in something like

// haversine formula - error margin 3m per km

makes sense. Any other developer would be able to see it’s limitations and determine if this was suitable for their needs.


#76

Holy crap, is this bizarro world? Programmers are writing TOO many comments? I’ve never heard such a thing! I wish this was in line with my experience.

Just because I am a programmer and I can read code, does not mean I should have to. I’m not a compiler. Sure, I completely, 100% agree that code should be self-documenting where ever possible. On the outskirts of code, you will likely have some type of controlling logic which creates objects and calls functions, all of which should be fairly self-documenting and the flow is obvious and beautiful. These are the trivial cases. But as you get deeper in the meat and potatoes of the code, it becomes harder and harder to understand the code as immediately as the trivial parts. Instead of reading the code like a book, you have to start parsing the code like a compiler. It’s inevitable. Not everything can be broken into a 4-line function with a nice name. In these cases, a simple // XX does YY and then ZZ makes all of the difference in readability. Not only that, but it shows the programmer’s intent. If there happens to be a bug in this area, I can identify what the programmer was trying to do, why her assumptions were wrong, and thus fix the bug. Self-documenting code is completely worthless if it’s inadvertently documenting the wrong thing.

Really, the issue here, is the maintenance phase of the programming life cycle. As we know (From Facts and Fallacies), the maintenance phase consumes 40-80% of the total costs of a project. And maintenance programmers spend 50-60% of their time deciphering the code they are maintaining (Code Complete, referencing another source). So the question is, do comments help this deciphering phase? Yes. They do. They help more than not having them, that’s for sure! I’d rather have too many comments than not enough. I think it’s plainly obvious, but I’m sure there are studies that support it. Here is one with a few seconds of google searching:

http://csdl2.computer.org/persagen/DLAbsToc.jsp?resourcePath=/dl/trans/ts/toc=comp/trans/ts/1988/09/e9toc.xmlDOI=10.1109/32.6171

Any time you have code that is going to need published documentation, JavaDoc-esque systems do take a lot of space comment-wise, but if you need to maintain documentation anyways, it’s easier to do it right there in the code. It just takes a bit of discipline to remember to update the doc block if necessary whenever you are doing something in the code. Much more convenient than maintaining documentation elsewhere. And it may be useful to other programmers looking at the code, too.

It seems like there are a lot of posts on this blog and associated blogs with the tone of: Generally accepted good thing here is actually TERRIBLE!!! OMG!!!. This is reminiscent of cable news network scare tactics and nonsense to start controversy when there really shouldn’t be any. Yes, using comments, design patterns, regular expressions, XML, etc to the extreme is bad. Of course. This could be said about anything. But what should be known is that they are generally good things, but should be used correctly, with care, and under the appropriate circumstances. Self documenting code and comments are both things a programmer should use and continually attempt to get better at.

Preaching the correct way to use these things is probably going to be much more helpful for those you are trying to address. I see that you aren’t saying all comments are bad- But that is certainly the tone. It’s not until the last sentence that you admit there may be a use for them. I think people like you, Sammy, and others currently on an anti-comment binge are only going to hurt yourselves if you are so strict and unwavering in regards to code commenting.

The effort it takes to write them is vastly (and I mean VASTLY) overstated and the space it takes up on your screen an irrelevancy, as far as I’m concerned (Ignore the dark-green text!). You act like a programmer needs to be a novelist to write simple comments. I think I’ve seen people have a harder time naming functions appropriately.

In short, I don’t think you are young enough to be so idealistic :slight_smile:


#77

It’s not possible to overcomment something in reality.
This is another one of those bull$hit macho, ‘I don’t need comments in MY code’ threads that should become ignored.

Jeff, why don’t you go and re-read one of your favourite books, the Mythical Man Month, to hear all about this discussion and why you are wrong?


#78

Not quite the same thing, unless those comments stay in the code after you’ve written it!

But, that’s what Steve Mcconnell suggests in Code Complete.


#79

Another related issue is use your source code control and don’t use comments as a kind of historical record of code that has been replaced. It works for a couple of iterations in case your refactoring broke something - maybe - but 20 iterations later it’s plain dangerous.

Be brave, delete stuff and trust in your source code control system.


#80

But I like telling myself stories as I wrote code! Honestly, the layman’s-terms expression of the function of whatever I happen to be developing is actually helpful, I’ve found, in keeping my own thoughts straight. So while I might have 4 times as many comments as you might recommend, I feel like my development process has been smoother and less convoluted. It probably helps solidify new concepts too.

However, before I hand my code over to another developer, or particularly before I deliver it, I strip out all my ‘note to self’ comments and rewrite things a lot more sparsely. It’s kind of redundant, I know, but it works for me, so I figured it’d be worth mentioning.