Coding Without Comments

If peppering your code with lots of comments is good, then having zillions of comments in your code must be great, right? Not quite. Excess is one way good comments go bad:

This is a companion discussion topic for the original blog entry at:

I agree! Comments in code are a double edged sword; they’re become like more code to maintain. And if no one is maintaining them, they become downright dangerous.

I use comments sparingly, and only to tell what’s being done and how. Usually in the form of one-liners.

what the hell is a comment?

That’s just job security. I’ll do one better… insert lies and comments that make no absolutely no sense.

Relax, I kid… I kid…

I’ve found, when looking back at really old work, that the comments were nothing more then psuedo-code typed before actually making things work.

When I look at my systems today, about the only comments I find (other then TODO stuff) are notes about the business rules being implemented by the code and even then only when the business rules are intuitively obvious.

For instance, in my current project I need week numbers. However, we base week numbers by starting from the last monday of the year before. That’s weird enough to actually document as a method named GetWeekNumberStartingFromLastMondayOfPreviousYear is just silly.

I’ve heard arguments for using comments during maintinance to show what was tried, but frankly, if you’re checking in your work on a regular basis, you already have that history.

Hm, you should still have a comment in that code snippet stating it uses Newton-Raphson approximation, IMHO. And you definitely don’t want that as part of the function name. Heck, even having Approximation in the function name might be putting too much implementation detail in the function name, unless you’re dealing with a common code library that just might be picked up by engineering.

Oh, and you’d definitely also want some error margin information as part of the function comment… in case somebody from engineering even considers using the routine :slight_smile:

r = n / 2;
while ( abs( r - (n/r) )  t ) {
  r = 0.5 * ( r + (n/r) );
System.out.println( r =  + r );

Isn’t (n/r) always 2?

never, ever start with comments.

Unless it’s inline extractable API docs like javadoc of pydoc, of course.

One problem with your example is that it’s taken from numerical analysis, where knowing HOW the computations are made is essential to judging their accuracy for various inputs. Saying This subroutine computes X doesn’t convince anybody that it’s accurate.

Which brings me to your square-root example. Your final version tells me that the code approximates the square root. However, without a comment to tell me that Newton’s method is being used, I cannot know this without spending time examining the code closely and having seen Newton’s method in an algorithm before. Most developers would give up well before they make that realization — forcing them to ask you to explain the algorithm and convince them of its correctness, which wastes more of your time than it would take to write the comment.

The only problem with writing understandable code is that many programmers have no idea how confusing their stuff is. Sure, it’s 20 pages of unorganized cryptic statements, but THEY understood it. Surely if someone else doesn’t understand it, they must be lousy programmmers.

I find that when I stub out a method, I pseudocode it first with comments. This helps me think through the logic and scope of the task and generates a roadmap that I can return to if I’m interrupted.

It seems to generate very useful comments for others to follow later.

never, ever start with comments

I find I write my code cleanest when I start by filling in my methods with what they ought to do in comments, then filling in what they actually do after I’ve got my architecture down.

And, if I comment in the API doc style of the language, I get nice documentation to boot, as mentioned before.

I couldn’t agree more. When I was a junior developer I used to bemoan the lack of comments in code created by my more senior team members. Now that I am a lot more experienced, a lot of comments tend to clutter up the code and reduce the comprehensibility.

Generally, comments tend to be wrong, or confusing. In addition, there is a tendency to comment code that is changing, or complex. When that code is modified further, the comment becomes out of date, but the instinct is to leave the comment in just in case. Before long, nobody knows what a comment means, or why it could possibly be there.

The best comments are like the ones shown in the article. Short and to the point. If you are implementing a particular algorithm, then say so (perhaps with a link to an article explaining the method), but don’t overload the reader with useless detail that is covered in the code.

I think comments are important because most of the programmers actually out there working are pretty hopeless. I may be able to write well-structured, clean code but the rest of my team won’t understand it because they’re very inexperienced. However, they’re all we have.

The same happened to me when I tried to open up DNN when I was new to Beautifully written code, not a single comment, full of bugs. I couldn’t make head or tail of it.

Leave the comments on for all the people who aren’t brilliant, tireless programers.

I will side with the people who say that badly maintained comments are worse than no comments. Comments in the code are code and need to be maintained as such; but there’s no compiler or interpreter to tell you about the dependencies.

My own code tends to be tersely commented at best; the one time I remember writing about 25 lines of comment for three lines of code was because those three lines were getting around a bug in Windows 3.1 and there was no URL I could point people at to read about it…

Most of my comments contain the url from where I stole the particular bit of code from. Tests explain things much better than comments can. Talk is cheap. Show me the code.

Just as others, who have already mentioned it, I too write comments before writing a line of code, as a way of helping me think things through; and I see nothing wrong with that.

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

SquareRootApproximation(n, Type.NewtonRaphson)

You can save on writing comments by designing every piece of software around a concept of software factories vomiting objects but looking really understandable, by-the-book academically cool.

Or you can write compact code, based on well thought-out usage patterns, not some over-engineered ego-busting monster that compiles, runs but cannot be reused.

Key problem: some comments can’t be expressed through functional decomposition.

I agree that algorithm and data structure explanation should be done largely through functional and OO decomposition and member and type naming, and that this is one of the big reasons why naming is so important, but there are other aspects to programming than call-tree decomposable algorithms and trivially modular data structures. Not all problem domains and corresponding solution abstractions are representable in a first-class way using the tools of structured programming and object-oriented design.

What about global* state changes that affect horizontal sections of code, rather than the vertically-oriented call tree of a functional decomposition?

(* or local to a large object graph - functionally not all that different)

What about concurrent programming, where every cross-thread-visible operation is only correct when every possible relevant state of every other thread has been considered?

What about older programs written in older languages using older techniques - I’m thinking of IDE compilers written in C with extensive global state, discriminated unions and semantic field reuse across different stages, in particular (since it’s my day job). A few comments go a long way in these kinds of situations - particularly since one doesn’t have the luxury of writing it correctly the first time, even presuming that the right abstractions are available in any single programming language.

Code that has been maintained for decades generally doesn’t have an immediately understandable gestalt such that it can be immediately refactored and rewritten more clearly, and in these situations comments are vital to help build up that gestalt, so that future refactorings can occur.

Motivating example: you’ve got a data structure graph that represents a parsed piece of code, and you’ve got to do manipulations, optimizations, debug info extraction, and code generation - and do it all as fast as possible with minimal copying and reallocation etc. Classes don’t sit well with the requirements - you want to separate out your parsing logic, debug info, optimization, code generation, etc., rather than lumping them all into a single class. Each of those phases will want to annotate the graph for its own purposes, but those annotations can go away when the phase is done. You end up using discriminated unions or something similar, along with functional pattern matching or a visitor pattern, etc.

I can assure you that that code (and data structure types) will improve with the addition of a few comments :slight_smile: