One of my favourite Ruby Rogues episodes (What Makes Beautiful Code) has a short section where the Rogues talk about the concept of dishonest code. David Brady wrote a really good piece on this, which I highly recommend reading.

What I want to talk about is a more specific variant of dishonest code: dishonest comments.

Take this code, for example:

$('a').click(function(e) {
    e.stopPropagation();
    e.preventDefault();
});

If you’re not familiar with JavaScript events, e.stopPropagation() will stop this event from bubbling up to other event handlers. Now, what if somebody decides that the event should bubble up? They might do something like this:

--- a/example.js
+++ b/example.js
@@ -1,4 +1,4 @@
 $('a').click(function(e) {
+    // Let the event bubble up to the next handler
-    e.stopPropagation();
     e.preventDefault();
 });

This is pretty common practice; a developer will leave a comment so that the next person understands why the e.stopPropagation() is gone.

So far this isn’t too bad. But what happens when somebody changes their mind again, and doesn’t want the event to bubble up anymore? Quite often, this is what happens:

--- a/example.js
+++ b/example.js
@@ -1,4 +1,5 @@
 $('a').click(function(e) {
     // Let the event bubble up to the next handler
+    e.stopPropagation();
     e.preventDefault();
 });

The e.stopPropagation() call is added back in, right where it was before. You can see the problem here: the comment explaining that the event will bubble up is still there.

A lot of developers tend to ignore comments in code, especially comments that were written by somebody else. Modern text editors and IDEs are partly to blame for this, since their syntax highlighting tends to de-emphasise comments by greying them out.

$('a').click(function(e) {
    // Let the event bubble up to the next handler
    e.stopPropagation();
    e.preventDefault();
});

What we’ve ended up with is a comment which says one thing, and some code which does something entirely different. This is surprisingly common – most codebases are absolutely littered with dishonest comments.

The example I’ve given above might seem contrived, but this is an entirely real —although somewhat simplified— example of some code that I had to debug recently.

Dishonest comments can confuse even the most experienced developers, and make debugging much more difficult than it needs to be. Figuring out what one line of code is supposed to do can turn into an hour of trawling through version control logs and diffs.

The worst part about dishonest comments is that the problems they cause aren’t immediately obvious. Unit tests won’t pick them up. A full regression test won’t find them. Once they’re committed to the codebase, they remain hidden right up until the point where you realise that they’re lying to you.

So really, the only way to avoid dishonest comments is to simply not write them in the first place.

In the Ruby Rogues episode I mentioned at the start of this post, there’s a brief discussion about the idea that comments are a code smell. This idea is hotly debated. However, I do believe that treating comments as a code smell can help you to identify dishonest comments before they become a problem.

I think this ends up coming back to the way that syntax highlighting hides comments from us. It’s really difficult to spot dishonest comments because we’ve trained our brains to focus on the bright & colourful text, and ignore the dull grey text.

Greyed-out comments
Greyed-out comments

If you opened this file to make some changes, chances are you wouldn’t even notice the comments, let alone figure out that they are all lies. But what if the comments stood out more?

I’m currently experimenting with my own variation of the Monokai colour scheme which draws comments in a bright colour.

Bright comments
Bright comments

Suddenly the comments stand out. They even stand out more than most of the actual code in this file. To me, this is a good thing because comments should only be there to say something important that the code can’t say by itself. If there is a comment in the code, I want it to stand out because it must be telling me something really important.

Having the comments stand out more also makes it much more obvious when there are too many comments. Usually, seeing a lot of comments tells me that either:

  1. Most of these comments are unnecessary, or,
  2. The code needs to be refactored to be self-documenting

If the comments are unnecessary, they can be removed. If the code can be more self-documenting, then the comments that were documenting it can be removed. Either way, you end up with less comments, and less dishonesty.

How you deal with dishonest comments in your codebase is up to you. In the end though, it’s down to you and your team to be more thoughtful about the comments that you write. If an honest comment can be turned into a dishonest comment simply by changing the code around it, then you probably need to re-think whether that comment is necessary.