Code Tells You How, Comments Tell You Why

In an earlier post on the philosophy of code comments, I noted that the best kind of comments are the ones you don't need. Allow me to clarify that point. You should first strive to make your code as simple as possible to understand without relying on comments as a crutch. Only at the point where the code cannot be made easier to understand should you begin to add comments.

It helps to keep your audience in mind when you're writing code. The classic book Structure and Interpretation of Computer Programs, originally published in 1985, gets right to the point in the preface:

Programs must be written for people to read, and only incidentally for machines to execute.

Knuth covers similar ground in his classic 1984 essay on Literate Programming (pdf):

Let us change our traditional attitude to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.

The practitioner of literate programming can be regarded as an essayist, whose main concern is with exposition and excellence of style. Such an author, with thesaurus in hand, chooses the names of variables carefully and explains what each variable means. He or she strives for a program that is comprehensible because its concepts have been introduced in an order that is best for human understanding, using a mixture of formal and informal methods that reinforce each other.

If you write your code to be consumed by other programmers first, and by the compiler second, you may find the need for additional comments to be greatly reduced. Here's an excellent example of using comments as a crutch:

This is a snippet of code from a well funded, closed-source system that has been deployed in production for years.

float _x = abs(x - deviceInfo->position.x) / scale;
int directionCode;
if (0 < _x & x != deviceInfo->position.x) {
    if (0 > x - deviceInfo->position.x) {
        directionCode = 0x04 /*left*/;
    } else if (0 < x - deviceInfo->position.x) {
        directionCode = 0x02 /*right*/;
    }
}

This is equivalent to the following, more readable code, with a bugfix.

static const int DIRECTIONCODE_RIGHT = 0x02;
static const int DIRECTIONCODE_LEFT = 0x04;
static const int DIRECTIONCODE_NONE = 0x00;

int oldX = deviceInfo->position.x;
int directionCode = (x > oldX)? DIRECTIONCODE_RIGHT
                  : (x < oldX)? DIRECTIONCODE_LEFT
                  : DIRECTIONCODE_NONE;

Note that more comments does not mean more readable code. It didn't in this example. The comments in the snippet above – if you even noticed them – only clutter the code even more. Sometimes fewer comments makes for more readable code. Especially if it forces you to use meaningful symbol names instead.

Although there are almost infinite opportunities to refactor and simplify code to obviate the need for comments, explaining yourself exclusively in code has its limits.

No matter how simple, concise, and clear your code may end up being, it's impossible for code to be completely self-documenting. Comments can never be replaced by code alone. Just ask Jef Raskin:

Code can't explain why the program is being written, and the rationale for choosing this or that method. Code cannot discuss the reasons certain alternative approaches were taken. For example:

/* A binary search turned out to be slower than the Boyer-Moore algorithm for the data sets of interest, thus we have used the more complex, but faster method even though this problem does not at first seem amenable to a string search technique. */

What is perfectly, transparently obvious to one developer may be utterly opaque to another developer who has no context. Consider this bit of commenting advice:

You may very well know that

$string = join('',reverse(split('',$string)));

reverses your string, but how hard is it to insert

# Reverse the string

into your Perl file?

Indeed. It's not hard at all. Code can only tell you how the program works; comments can tell you why it works. Try not to shortchange your fellow developers in either area.

Related posts

I Fight For The Users

I Fight For The Users

If you haven’t been able to keep up with my blistering pace of one blog post per year, I don’t blame you. There’s a lot going on right now. It’s a busy time. But let’s pause and take a moment to celebrate that Elon Musk

By Jeff Atwood ·
Comments
Updating The Single Most Influential Book of the BASIC Era

Updating The Single Most Influential Book of the BASIC Era

In a way, these two books are responsible for my entire professional career. With early computers, you didn’t boot up to a fancy schmancy desktop, or a screen full of apps you could easily poke and prod with your finger. No, those computers booted up to the command line.

By Jeff Atwood ·
Comments
To Serve Man, with Software

To Serve Man, with Software

I didn’t choose to be a programmer. Somehow, it seemed, the computers chose me. For a long time, that was fine, that was enough; that was all I needed. But along the way I never felt that being a programmer was this unambiguously great-for-everyone career field with zero downsides.

By Jeff Atwood ·
Comments
The Raspberry Pi Has Revolutionized Emulation

The Raspberry Pi Has Revolutionized Emulation

very geek goes through a phase where they discover emulation. It’s practically a rite of passage. I think I spent most of my childhood – and a large part of my life as a young adult – desperately wishing I was in a video game arcade. When I finally obtained my

By Jeff Atwood ·
Comments

Recent Posts

Stay Gold, America

Stay Gold, America

We are at an unprecedented point in American history, and I'm concerned we may lose sight of the American Dream.

By Jeff Atwood ·
Comments
The Great Filter Comes For Us All

The Great Filter Comes For Us All

With a 13 billion year head start on evolution, why haven’t any other forms of life in the universe contacted us by now? (Arrival is a fantastic movie. Watch it, but don’t stop there – read the Story of Your Life novella it was based on for so much

By Jeff Atwood ·
Comments
I Fight For The Users

I Fight For The Users

If you haven’t been able to keep up with my blistering pace of one blog post per year, I don’t blame you. There’s a lot going on right now. It’s a busy time. But let’s pause and take a moment to celebrate that Elon Musk

By Jeff Atwood ·
Comments
The 2030 Self-Driving Car Bet

The 2030 Self-Driving Car Bet

It’s my honor to announce that John Carmack and I have initiated a friendly bet of $10,000* to the 501(c)(3) charity of the winner’s choice: By January 1st, 2030, completely autonomous self-driving cars meeting SAE J3016 level 5 will be commercially available for passenger use

By Jeff Atwood ·
Comments