I've given this talk at several meetups and a conference, and thought it might be worth writing down as well. The conference recording is embedded here at the top (the link is here), and the wall of text follows below. You can find the slides here.
The motivation for this piece comes from something I consider downright frustratingly true:
"Bad documentation is worse than no documentation."
— some wise people (and also me)
When you have no documentation, you're left with the code itself. While quite possibly subpar in any number of ways, at the very least it's honest, in the sense that it simply does what it does.
When you have poor documentation—especially if it's incorrect—you may find yourself misled and your time otherwise wasted.
As such, I'm a big believer in having either useful documentation or none at all. Since the former is far preferable to the latter, here we are.
To make sure we're on the same page, let's review some basics.
They're # this stuff
in Python, // this stuff
in many other languages, and /* this stuff */
in others. They're annotations sprinkled throughout your source code meant to provide some form of context to the reader.
"Programs must be written for people to read, and only incidentally for machines to execute."
— Harold Abelson, Structure and Interpretation of Computer Programs (1979)
Comments are part of code, so the above quip holds doubly true for them.
They're for everyone except you at the time of writing them—me, you in six months, and everyone else. Humans are pretty terrible at reading minds, and this really helps.
Here's the list before we go into detail about each one:
Here's a screenshot of my editor with the theme I use:
Here are a few more screenshots of various themes:
The one thing they all have in common is that they don't make comments very prominent. In fact, they very intentionally hide them quite a bit. This is a problem, because invisibility is bad.
Invisible things are easy to ignore. Thus, invisible comments get ignored. As a result, these ignored comments suffer in quality. The two most common problems this causes are outdated comments and commented-out blocks of code.
Making comments more prominent doesn't magically fix them, but it does motivate you to consider them more often. If you're forced to read outdated comments because you can't gloss over them, you'll update them. If you have to scroll past giant blocks of commented-out code, you'll delete it.
I fix this problem rather simply:
I make comments the most prominent thing on screen. This has made me far more eager to improve them in my day-to-day work.
Things may get a little uncomfortable here, but we need to dispell a surprisingly popular myth:
"Code is self-documenting."
In reality, the best-case scenario is that code can self-document what happens. The comments answer the "why" questions, such as why is this here (as opposed to somewhere else), why is this done this way (as opposed to any number of other ways), and why is it done at all.
As an example, here's a line of code yours truly wrote a few years ago:
file_data = file_data.replace("\\\\\\\\", "\\\\")
You don't even need to know any real Python to get the gist of what's going on there—we're replacing every instance of eight backslashes with four in some variable file_data
. Simple enough.
If I were to document this poorly, I'd write this:
# replace 8 backslashes with 4
file_data = file_data.replace("\\\\\\\\", "\\\\")
While technically correct—the best kind of correct—the comment adds no value and is thus useless.
If I were to try and be clever while investigating this later, with no context, I may end up with something like this:
# wat? why. just why.
file_data = file_data.replace("\\\\\\\\", "\\\\")
And if I were a bit younger, perhaps I'd write this:
# y tho
file_data = file_data.replace("\\\\\\\\", "\\\\")
But what I should write is something like this:
# This file is submitted with backslashes escaped,
# the validator escapes them again, and the first
# round of processing does it *again*, so here we
# remove the last layer we don't actually want.
file_data = file_data.replace("\\\\\\\\", "\\\\")
Now the code explains what happens and the comment explains why it happens. At this point the whole thing seems a bit weird, so we can add a little feel-good note at the top:
# TODO: clean up this whole escaping mess
# This file is submitted with backslashes escaped,
# the validator escapes them again, and the first
# round of processing does it *again*, so here we
# remove the last layer we don't actually want.
file_data = file_data.replace("\\\\\\\\", "\\\\")
This may seem shocking, but there are no points awarded for brevity at the expense of thoroughness. Yes, rambling is bad and there absolutely is such a thing as too much documentation, but the opposite is more frequently the case.
This also may seem shocking, but it's perfectly OK to have more comments than code. This goes for any single section and even entire projects. The extra bytes of text really shouldn't be an issue in this day and age.
With apologies to everyone working in an open office, I suggest that you at least sometimes take the time to read your comments out loud. You'd be amazed at what you can hear!
Language matters, and how we consume it affects our perception of it. When you read something silently to yourself—especially if it's something you wrote recently—you'll skim more than you'll actually read. Reading it out loud forces you to slow down and pay closer attention.
You'll catch typos much more effectively. Bad grammar will stick out like a sore thumb. When writing that last bit of documentation after a particularly long day, you'll stand a better chance at not writing gibberish.
You already ask for feedback on your code, likely through code reviews. Your comments shouldn't get a pass on this.
Getting experts to read your comments lets them verify correctness and completeness. Getting those unfamiliar with the code, language, or problem domain lets them verify clarity. And everyone can point out obvious issues.
If you're wondering whether this is really necessary, keep in mind that great writers have great editors. Or listen to Kurt Vonnegut at least:
"Be a good editor. The Universe needs more good editors, God knows."
— Kurt Vonnegut, Letters (2014)
To save you scrolling back to the top, here's the list again, as my parting gift to you:
Now go forth and comment!
Thanks for reading! You can keep up with my writing via the feed or newsletter, or you can get in touch via email or Mastodon.