Wednesday, December 3, 2014

A Case Against Comments

Want to hear something opinionated? Comments are a code smell. There, I said it. And I don't apologize for it.

All comments? Well, maybe not necessarily. I'll concede that there are exceptions to the rule. Header comments which drive intellisense can be useful, for example. Though, seriously, they don't need to be on everything. I'll also concede that once in a while there's an exception to the rule where the purpose behind a particular implementation could require a little more explanation. Comments like, "We use the magic value 3 here because Vendor X's product requires that. Don't let this magic value leak from this dependency implementation." for example.

But by and large nearly all of the comments I see in real-world code are a code smell. Why? Because they don't add value. They take up space (not as a measure of bytes in the file, but as a measure of time spent understanding and supporting the code), they clutter the code, and they offer no information that the code shouldn't already have.

I can already hear the responses from every manager, owner, alleged developer, etc... "But without comments how will we know what the code is doing?" As usual, someone else has said it better than I can:
That's the gist of it, really. If a developer on the team isn't able to convey the business logic in a structured and meaningful way, what good are that developer's comments going to be? Does that developer even understand what he or she is writing? If not, aren't those comments just going to add more confusion and misinformation?

Robert Martin has been known to say, "Every comment is an apology." That apology is basically the developer saying that he or she wasn't able to express the meaning in the code, so he or she gave up and just wrote the meaning in comments instead. It's just that... giving up.

My own take on it is, "Every comment is a lie waiting to happen." That is, either the comment is saying something that the code isn't saying (so it's lying) or the code is going to change at some point and invalidate what the comment is saying (so it will be lying).

(And please don't say that we can simply enact a policy whereby developers must update the comments when they update the code. And those updates must be peer reviewed and documented and all that nonsense. Policies like that demonstrate only one thing, that the people enacting those policies have no actual meaningful experience leading a team of software developers.)

Think of it this way...
When you're reading code with lots of comments, do both the code and the comments unambiguously tell the same story?
If not, which one tells the correct story? Which one should tell the correct story? And why should the incorrect story also be told?

If they do both unambiguously tell the same story, then why does that story need to be told twice? Doesn't that violate DRY? What happens when one of their stories changes? Will the other change in the exact same way?

The story need only be told once. Tell it in the code.

1 comment:

  1. I agree with the premise, but I disagree with the characterization that comments and code tell the same story.

    To me, comments are like annotated religious texts. You find in one column the actual text, then immediately following in the adjacent column, you find a modern elaboration of the meaning, with cross-references to other relevant information.

    Written well, comments clarify the intent. But, it's damn hard for the programmer writing the code to context switch into a mode where she can clarify her intent. Religious texts only became annotated hundreds of years after they were written, and here's where I circle back around to agreement:

    Write the code first, forget comments. When you, or anybody, comes back to that code, and you read it and have a WTF moment, take time to refactor, don't comment. Repeat until you have a WTF moment but can see no other way to refactor. Then comment.

    This strategy relies on comments as a last ditch, archaeological effort to explain what's going on.