Some will tell you that good code is self-documenting. In other words, if you write clear code then you won’t need comments.
Is that true, though? Even high level languages are designed to suit the computer, not the programmer. You can write impractically long variable names and avoid syntactic shortcuts all you like but there’s a tonne of human context that gets lost in code.
As the saying goes, code is read more than it is written.
So, think about that future reader. It could be you in six months’ time. Or how about a colleague during code review? Maybe an open source contributor you’ll never meet or speak to. However it happens, there’ll come a time when someone is reading your code and they won’t have the benefit of all the context you’re holding in your head as you write it.
Documenting your code doesn’t need to be painful. Here are four ways code comments can help both you today and that future code reader to understand what on Earth it was you were trying to do.
Jeff Atwood says that, “Code tells you how, comments tell you why”. You should use comments to explain both why your code is written the way it is and why it behaves the way it does.
Let’s look at an example. Say your code calls an external API. Most of the time, each API call completes without problem. From time to time, though, API calls result in an error. Usually you can just retry and the call completes.
You’ve noticed, though, that three or more errors in a row usually means that there’s a problem at the API provider’s end and retrying immediately won’t help.
So, you want to limit the number of retries and do something different if there are more than three errors. Your code ends up looking something like this:
while $error_count < 3 {
call the API
if response_code == 200 {
$error_count = 0
break
} else {
$error_count += 1
}
} else {
$error_count = 0
use a cached value instead
}
To anyone reading, that error count might seem arbitrary. Why three and not four? Using a comment, you can explain the context that led you to choose three retries:
The remote service can be flakey so we retry, but it rarely succeeds after three consecutive errors. Instead, we need to use a cached value.
The code itself tells the interpreter or compiler what to do. The comment tells other humans why that particular set of actions was necessary.
Writing code comments is a little like teaching. Often, when we come to teach something to someone else it reveals the limitations of our own understanding. If you can’t explain something simply, then perhaps you don’t truly understand it yourself.
Explaining your code in comments is an opportunity to check that you made the right decisions. It’s not so much about confirming you understand what you did but whether it makes sense when explained to someone else. What seemed like a great idea in the heat of coding might fall apart when you need to justify it afterwards.
Use your code comments to anticipate other people’s objections. If you find yourself agreeing with those objections, go back to the code and take a different approach. Otherwise, use the comment to explain why those objections don’t apply.
If code gets read more than it is written then it gets scanned more than read.
It’s likely that the first thing you do when opening a new code base is pick a file and scan through it to get an idea of what that code does. Method, object, and variable names can certainly help but, if the aim is to inform future developers, they’re not enough.
When you’re documenting a class, module, or function, start off with a one-line summary. Make it brief and direct. Think of the person reading through this code late at night who is under pressure to fix a customer-facing bug long after you’ve moved to another job. Think about the junior developer looking to learn from your code.
Similarly, write in the imperative. “Remove duplicate entries from the customer list” is more efficient to read than, “This removes duplicate entries from the customer list”.
Just as code comments explain your code without people necessarily having to read the code itself, so you should make that explanation available in an easy to use format outside of the code itself.
Let’s say you’re providing an API. It’d be unfair to make your users open your source files to understand how to use it. Instead, you can generate a good first draft of user facing documentation from your code comments.
Each mainstream language has its own utility for generating code from your comments. If you’re new to a particular language, you can pretty much guarantee that adding “doc” to some part of the language’s name will reveal the documentation generator. JavaDoc, JSDoc, Pydoc, Perldoc … you get the picture.
Purists would hope that the code itself is enough but that’s ignoring that comments are part of the code. The code is not there merely to tell the interpreter or compiler what to do, it is also there to serve the humans who produce and maintain it.
This has two main implications. First is that you should factor code documentation into your time estimates. Take as much care over your written English (or other human language) as you do over writing beautiful code.
The other is that code updates will require comment updates. This should become an explicit part of your process, otherwise it is too easy to miss. In particular, your code review checklist should have a step that checks if changes to the code are reflected in the code comments.
Not everyone likes writing comments or documentation of any type. However, don’t think of it as a chore. Instead, think of it as a letter to a future developer. And you should probably be kind to that future developer because, after all, it might just be you.