Sometimes I see devs say things like "good code doesn't need comments". The rationale being, if your code is well-written, it should be self-explanatory to the next developer that's looking at the code.
Actually I used to say that as well, but that was mostly because I was (and maybe still is?) quite a lazy commenter. I thought "how would I not understand my own code?" as long as it's written clearly enough? Don't even get me started on writing design documents or maintaining them, but I'll leave that for another topic.
But at some point I started to appreciate comments, so I'd like to share my thoughts on it by sharing some experiences I've had while writing code, which might offer some insight into why even the best code might benefit from having comments.
Story Time
I wrote an article previously about web scraping. If you're interested in scraping or having issues with getting scraped, might be something to read, but it's not related to this story besides that I write various random tools like scrapers and bots.
In particular, my tools come in different flavours
- some of them run on a server constantly listening to web hooks
- some of them wake up once every hour or so to poll for data
- some of them fire up a browser to navigate a couple pages
- some of them transform data from one format to another as part of a pipeline
Basically they all do different kinds of things. They're all tools that are written to solve specific problems, and most of these deal with completely different problem domains. Some of these scripts are about 10-20 lines long, others might be 100+.
I have dozens of these small tools lying around, some of them I've never looked at for years but still in use.
Why Did I Write That Again?
Websites will change. API's will change. Data formats will change.
Basically, requirements change. It's just how things are and you just have to deal with it when it happens. If you're lucky, things might not change that often, but on the flip-side, because it doesn't change that often, you don't look at your code that often either.
Eventually you'll start forgetting details, and one of the most frequent problems I've had when one my tools crashes is I have no idea why my code is doing what it's doing!
How Self-Explanatory is Good Code?
When I look at my code, I know exactly what it's doing, because I came up with descriptive variable, method, and class names. I have spaces after each comma, and good indentation or curly brace placement to make that code look clean and absolutely fabulous.
Indeed, it should be quite self-explanatory what the code is doing, but there are so many things that self-explanatory code fails to explain
- Is this code correct?
- Why is it written this way?
- How should this code be used?
- What problem is the code meant to solve?
- Are there better ways to solve the problem?
Of course, "what is this code doing?" is an important question as well, but that's just one out of many other important questions that I have when I look at a piece of code.
Beyond My Code
At some point, I started moving away from only reading and writing my own code. I started using libraries. I started using frameworks. I started code-reviewing. I started extending other developers' code.
Not only do I need to understand the problem, I also need to understand how you've attempted to solve the problem through your code. I might be able to understand what your code is doing, but then I might have to put it all together to understand why you wrote it that way.
Most of the time it's not like my 100-liner simple tools that do just one or two jobs, some of these could be massive 100000+ line codebases with hundreds of classes and components written by dozens of developers over the course of many years.
It really can take a lot of time to truly understand what the code is doing, and not having any comments to help explain the purpose of the code can make it that much harder to put things together before you can actually dig in and write something of your own!
We are Problem Solvers
The biggest lesson I've learned in software development is understanding my role as the coder. The code is simply a solution to someone's problem, and there's an entire process that you (or someone else) go through before you arrive at the final solution that will be turned into code and delivered.
By writing comments to explain the purpose of your code and a bit of the thought-process that goes into it, it will greatly benefit the next person (perhaps yourself even) who looks at your code and wonder why you wrote it and how it should be used.
Feedback?
What are your thoughts on comments to explain your code? Are there strategies to good code writing that can allow you to express your thought process without necessarily writing it as comments? I'd love to be able to read a piece of code and understand the big picture behind it since it minimizes the amount of text I'd have to write.
Top comments (11)
in my experience the shorter the code the harder it is to understand because as you said developers are problem solvers so when you find a unique way to solve an issue most of the time the solution would be short and fast especially when you solve an algorithm for example if i said write a code that sums numbers from 1 -> 1m most developers may write a loop but this problem can be solved with just one line with this equation
and if i see something like this without a comment i would freak out.
Sometime fastest code wear strange habits. In such case i prefer writing 50 lines of comment, than rewriting the optimal code.
This is interesting, could you give some examples in rough code?
Like fx. where would you suggest adding comments, maybe some specific instances where you remember a comment saved the day etc.
I'm a huge fan of verbose code, but i've been debugging for almost 14 years now. So i hardly spend much time figuring out how things work unless i am dealing with something entirely new.
So to be frank, i have a huge bias/blindspot.
So examples would help me a lot. :)
I haven't thought of a good example yet. The one in draft right now involves a method that generates a hash token by taking some data and manipulating it a specific way based on how the app does it, and then at some point the dev changed it which causes all my requests to fail.
Without comments, I couldn't remember why it was doing all if those things or how I even figured it out, so I had to go back and understand the app all over again. If I had simply wrote down where to find the algorithm, it would've saved me a lot of time.
But I don't know how relatable this example is.
A bit, Iβve had to add unit tests to enforce not changing certain Functions return values before.
Not all environments are unit test viable, I could see my self adding warning comments if that was the case. :)
That being said, changing the return type of something Is generally very bad, so my hope is that it would be caught in code review first.
Most of the tools I have rely on third party services/data formats, some of which are not designed with the end-user in mind (eg: proprietary formats, internal API's, etc) so I think the issues I'm running into are mostly because I'm doing things people shouldn't be doing lol
A well written unit test explains the contract of the code, what is it supposed to be doing.
And I am in the camp that comments are the exception instead of the rule. I do make a distinction between API documentation/architecture documentation and comments that explain what you are actually doing in the code.
I did expect to see examples in this blog so there was something concrete to agree or disagree with.
Thanks for the feedback. I think unit tests can definitely provide a lot of clues, especially with all of the possible inputs good (and maybe bad) inputs.
High-level documentation I agree should be distinguished from comments, though I believe some tools use class and method comments and such to generate API docs, so it would accomplish two things at once. Plus if I'm reading through the code, it would be easier to just see the comments right there instead of going elsewhere to reference the design docs.
Example is a good idea. I will think of something appropriate to illustrate the purpose of a comment and how it might be useful.
My opinion on this boils down to the fact that I have never been upset to see comments.
For myself I use a module explanation (by file or folder).
It include Nature and origin of data
The goal of the process or features of this module
Restrictions (valid data ranges and type) and pitfalls,
I don't use Var, less possible, No Lamba, or the minimum possible.
and i don't use no meaning locals like simple letter except for a basic iterations.
I Rarely stall on my code like before trying to understand what i did last year for example...
Thanks for the feedback. I like module-level comments as well, so if I see a folder with 10 files, I can go through each of them and quickly look at what purpose they might serve.
There are definitely a lot of language-specific syntaxes. Things that are considered "pythonic" for example might be quite unintuitive for someone that doesn't have a strong grasp of python, and they're spending more time trying to figure out what the code is doing.
If it's for performance reasons, comments are a good compromise because while I might not be able to understand how it works immediately, I can at least know why it's there and that it seems to do what it's supposed to do.