What’s the story about commenting?
Recently, there was a discussion on LinkedIn around comments, again! As usual, it appears that people either fall on the side of comment everything in this code or the side of avoid comments at all costs, even if there is a gun to your head. Moderation?!! any one?!!
This is not a new discussion. Every now and then one, person from one of these camps posts something and every one get on each other’s throats.
There are, of course, some people like me that are in the middle. From time to time, like this time, we get pulled into this discussion; despite all our past experiences that tells us, let it go! This happened before! it will happen again!
The issue is that both camps are right! How so? Despite being on the complete opposite side of this spectrum, both camps have valid reasons for why you should comment or why you shouldn’t comment. The main issue is that comments could be good if used properly; But it could be also bad if it is replacing best software practices. Both teams are correct about their reasoning. But not in their generalizations!
Let me put it this way. Your car has a horn. It is there to signal other people and cars about your presence and hopefully avoid accidents. So, would you start honking all the time from the moment that you start your car?! Do you just honk your way through an intersections? Well, you can do that like in the movies! But that is considered bad practice. Honking excessively is a bad practice, so would you stop honking all together? Would you choose not to honk at all cost even when you can warn others and avoid accidents; because honking is bad driving?
The answer in both cases is no. Well, I hope you answered no; otherwise, please see a doctor! I am not joking. I mean it. See a doctor if you answered yes to any of the above cases.
The same thing is going on with commenting. The people from the camp of “no comment at all costs” talk about the reasons why commenting is bad; and they are right! The people on the camp of “comment all the way” talk about why comments could be helpful. and they are right too! The problem is the generalizations. Both groups generalize their reasons and try to adopt their commenting practice even in the situation that their original reasoning is no longer valid.
It’s like you were having an ear infection and you used an ear-drop and your ear infection was cured. Now generalizing that ear-drop would cure all your future problems and you should use ear-drops even if you have stomach-flu!!! Of course ear-drop won’t help you with your stomach-flu! and people from the other camp say that you should not use ear-drop at all, even if you have ear infection, because ear-drop doesn’t help with the stomach-flu.
To summarize, although people from both camps are right, the issue is their generalization. They are really talking about apples and oranges, but in this case it is a bit harder to tell as it appears both camps are talking about the same thing, commenting.
Is this really happening?
You might say: “Naaah! This is not happening. People just do this on social media to get clicks and views”. Well, yes; Some people do that. People post all sort of things just to get more clicks and views even if they don’t believe in what they wrote, as long as it generates views and clicks.
We are not talking about those people, of course. In my career, long before social media, I have seen people that truly believed in one of these practices: i.e. commenting or not commenting. They truly believed in what they were preaching and I have more respect for these people even if I don’t agree with what they preach. At least they have integrity.
My experience tells me that moderation trumps extremism. No matter what type of extremism we are talking. Moderation is a better approach in long run. In short runs may be an extreme opinion wins and performs better, if you are in a short game. But in long run, moderations is always a better solution.
What does “Clean Code” Book say about commenting?
Unfortunately, people who preach the practice of “not commenting at all” always refer to “Clean Code” By Robert C. Martin as the source of authority on the matter of commenting practice. Two issues with this.
The book never actually claims to be the sole authority
From the very beginning it is mentioned in the book that:
Later in a section called: “Schools of Thought”, the authors clearly mention that there are multiple schools of thought. What they are proposing is based on their years of experience; and if you follow what they have done, you will enjoy what they have. They clearly say that:
To make it even more clear, the author says:
They also mention that:
If you are still in doubt and saying they are the authority, they put it clearly:
So, the author is never claiming “do as I told you, or you shall perish”. Not at all. The author is humbly saying that we tried this things for many many years on numerous projects, we thought hard and long about these things, and we got good results. They leave it up to you to follow or not.
So, it is a bit funny when people argue that that is the way and there is no other way, while the author is so humbly saying otherwise.
I have personally tried to adhere to the standards that they have presented in that book. There are may be few minute cases that I thought deviating from that school of thought might be actually beneficial. Honestly, most of those deviation are when I use Python and I am not using C/C++ or Java. There are certain things that I think requires a bit of tweak to make it better for that specific language. Other than that, I have to yet see a case that not following those recommendations is not actually helpful.
The book never actually claims not to comment at all
Chapter 4 of “Clean Code” book is dedicated to comments. That’s literally the title of the chapter: “Comments”. It starts with a quote from BWK and PJP:
The first sentence of the first paragraph of that chapter reads:
But then it goes on and says:
But still right after that it says:
The book continues with explaining why commenting could lead to trouble.
So to summarize, the chapter starts with a roller coaster of what the authors feel about commenting. They feel comments are bad; No, they are good, if well placed; But not that good; They are actually evil; but a necessary one! For the rest of that introductory section the text stabilizes on how comments could contribute to lower code quality.
Well, if you stop there and not read the rest of the chapter, I can imagine you come out with this understanding that: wow! what a bad things comments are. I should avoid using comments at all costs as this book says. At least that’s my theory why people, who became the member of “no comments at all” camp, base their source of beliefs on the “Clean Code”. They stopped reading the rest of the chapter.
If they had read beyond the “Comments Do Not Make Up for Bad Code” and “Explain Yourself in Code”, they would have noticed that there is an entire section of that chapter explaining when and how you can use comments or better to say you should use comments. But because they stopped, and never read any of those they concluded: “AVOID COMMENTS AT ALL COST”2.
I have no other explanation of why “no comments at all” people refer to that book; That book actually disprove the very same thing that they are claiming.
As for the people who claim “comment all the way”, my guess is that they haven’t read that book at all. My guess is that during their career, probably when debugging, they come up with a well placed comments in the code that helped them a lot to understand and finish their tasks; and they really appreciated a well placed comments and that shifted them toward believing that you should comment all the way.
The thing is that writing clean code is not easy. It takes time. Just like the saying that “Sorry I didn’t have time to write a short letter, so I wrote a long one”. With all the deadlines and work-loads I understand why sometimes even good and experienced developers tend to write a bad code in a short time and rely on comments to make that mess of a code readable and maintainable. I understand that. Don’t let that become a habit.
So what does “Comments are bad practice” mean then?
That could mean many things. But one thing that it DOES NOT mean is “you should not comment at all”. No, you should use comments. Don’t use comments to clean up the mess of a code. Don’t use comments as an excuse to accept bad code. Always ask yourself, can I write this code in such a way that doesn’t need comments? Is the alternative cleaner code more performing or at least the same in terms of performance? If you answered yes to any of these, then don’t comment.
What comments are good?
Ok, unlike clean code that firsts starts saying why you should not comment and then giving some good example and valid uses cases for comments, I start first with the cases that it is good to use comments.
TODO Comments
TODO comments as their names imply are things that needs to be done, but you can’t do it right away. Read the previous sentence again: “Things that needs to be done; BUT CANNOT BE DONE RIGHT AWAY”. If you can do it right away, do it. Don’t put a TODO comments. Don’t use TODO comments as an excuse to postpone things that can be done right away. You see. You can read this and say TODO Comments are ok. But notice that TODO comments are OK ONLY WHEN you can’t perform a task right away.
For example, I had to restrict the version of a library to a certain version which was not the latest. The latest version wasn’t yet approved by the security team for use in production. So, we did restricted the version of the library; but also created a ticket to remove the restriction once the latest version is approved, and put a comment on the code saying this needs to be remove; In the comment, we also referred to the ticket that was for this very same issue.
Informative Comments
The clean code book explains how it is useful to use an informative comments for regular expressions. Some regular expressions are very simple to understand. But regular expressions are quite powerful and you can get very creative with them. And those very creative regular expressions can be a bit harder to decode and understand. So, use a comment and in the comment say what that cryptic regular expression is actually doing.
Another case that I want to add to a valid use-case for informative comments is commenting one-liners. Some programming language allow you to combine multiple commands into one and get a task done in much shorter number of lines than if you want to expand it using for-loops and other structures. Sometimes, there is no added advantage to using one-liner other than saving some lines of codes. You are only making your code more cryptic without any added values. I would say don’t bother with those one-liner. Spell them out in more lines of code. But often times, there is some performance gains from using those one-liners. Python is known to be slow when you use for-loops. So, you would see a lot of one-liners there. In these cases, that you gain performance, not only one-liners are good, they are recommended. In this case, it is nice to have a comment above it and explain how that one-liners works; unless if the one-liner is one of the famous pattern; in that case, no comment is needed.
Self Explaining Code
Often times you would here that the code should be self explaining enough that doesn’t need comment. Let’s give an example:
// Updating Histogram
obj.runAlgorithmX42V2(input1, input2, ...);
// Getting Histogram data
some_array = obj.getResults();
Indeed you need comment in that code. Without those comments, you have no chance of knowing what really AlgorithmX42V2
is doing. You need to go to the implementation of the class that the obj is an instant of, and see what “AlgorithmX42V2” is really doing. Also, then getResults
? Is it returning the result of the same algorithm. probably! In this case it was. But then when you understand what the algorithm does, you are posed with this question that why would I ever want to run that algorithm but not get the results?!!! In fact, a quick search in the entire code base shows that it is always these two lines of code accompanied right after each other.
now consider this code:
some_array = obj.updateAndGetHistogram(input1, input2, ...)
Essentially, all we are doing is to wrap those two method that we always call one after each other into a single method, the benefits are:
- You don’t need to always write two lines of code: once update and second get the results.
- You don’t need to comment the code to make it clear that you are updating the histogram and now you are getting the results.
- If someone sees that line, they don’t need to go to the implementation of obj-class and decipher what those two lines are actually doing. That’s why originally we needed the comments.
- The other two methods also exists. So, if it ever happened that you wanted to just update the histogram but not get the results or you wanted to get a previously computed results, you are still able to call those methods. So, you are not limiting your capabilities.
- Now you don’t need to comment.
You might say but now I am adding a cost of function call; and all those things about stack stuff. Well, I have a news; The compilers are very intelligent these days. Try not to outsmart them. So, most probably the compiler with optimization flag is already in-lining that method. If it isn’t and If you want to be sure that it does, just flag the implementation of updateAndGetHistogram
as inline.
Making code Self-Explanatory is a race against time
This story actually happened. We had a code that was looking something like this (obviously it has changed from the actual code):
void some_function(some_inputs, int flag) {
/*
Some other comments here
flag == 0 Do blah blah
flag == 1 Do bleh bleh
flag == 2 Do bleep bleep
flag == well you get the point
*/
statement_1;
statement_2;
...
}
and whenever this function was called we had something like this:
some_function(inputs, 2); // doing bleep bleep
A colleague, a true believer in Clean Code book, submitted a CR and removed all the comments related to this. So the code was like:
void some_function(some_inputs, int flag) {
statement_1;
statement_2;
}
And later in other parts of the code:
some_function(inputs, 2);
All the comments were gone. So, we asked him why he removed the comments; and of course he started lecturing on how bad the comments are and referring to Clean Code book as to why we shouldn’t comment the code. It was actually at this moment we noticed that he is the follower of the clean code book.
So, after he was done explaining why the comments are bad, we started explaining to him that we agree that the comments are bad practice; and he is correct; we have read that book too. We explained that we could have written this code in such a way that it doesn’t need comment; But “comments being bad practice” does not mean to go in the code and just remove the comments. Actually now without the comments, the code is even worse. To make it cleaner, he would need to rewrite it so that it does not requires comments and that’s what it means saying “comments are bad practice”.
In this case, we decided to make the code more self explanatory by introducing an enum class:
enum class Actions{
DO_BLAH_BLAH,
DO_BLEH_BLEH,
DO_BLEEP_BLEEP
};
like wise the some_function
signature changed to use this enum, and we were calling it in the code as follows:
some_function(inputs, Actions::DO_BLEEP_BLEEP);
Of course, now that the signature was changing, everywhere in the code that this was used, we needed to make changes. Of course, the colleague was not super happy to do all this. But, he was kind enough to do it.
Fortunately, this module was internal to our group only and external groups and code repos were not using this. Imagine, however, that if this was a function that was widely used across the organizations. How many other code-bases would have needed changing? How many other manager would have blamed you for more works or missing dead-lines because you changed the signature of a method?
That’s why making code self-explanatory is a race against time. The longer you put it off, the harder it becomes. Just like the cancer. The longer you leave it and not treat it, it is harder to treat it. It would be a time that it is no longer curable. The same goes for codes. the longer you leave it, the more it is used, and then it becomes a much bigger task to fix. Quite honest, at some point, I wouldn’t blame you if you just want to keep the bad code as-is, just to avoid running away from an angry mob.
This story has a happy ending. We started another project and some of the very similar functionality was needed in that code-base. For some reason3, instead of making the old package a dependency, we decided to use the most common approach of software development, i.e. copy/paste/modify. After all, we are already doing a lot of that from stack-overflow. In that new version, however, we didn’t just copy/paste; we adopted a more proper form of Object Oriented development and that flag was not even needed anymore. It disappeared completely .
This reminds me of a saying:
As to why “Comments are bad practice”?
Now that we know what “comments are bad practice” means, and again, it does not mean not to comment at all, let’s look at why they are considered bad practice. There are two main reasons:
Hard to maintain
Codes change. There are many reasons that you might need to change a code. This post is not about that. We have a lot of mechanism available to make sure that the code is still behaving how it should be behaving even with the changes that we make to the code. The very first line of defense is our comprehensive unit-tests. right? If we make any changes to the code that is breaks something internally at least, unit-tests will catch them. If we make any changes to the code that some previously expected behavior changes, our unit-tests will flag it for us.
How about the comments? As of today, I am not aware of any automatic system that can check your code, and if the comment is no longer valid, flags it. Do you? May be with advances in NLP and LLMs we will have such system soon in future. Or if one already exists, let me know.
Many times I have come up with a code accompanied by a comment. The code is cryptic, so I said: “Good! At least there is a comment”. But only to read the comments and get even more confused and later figure out that the code was changed, the comment wasn’t.
If a comment says, this code is doing blah blah, but the code is doing bleep bleep; it takes you a while to figure out. And even when you have figured it out, you are still not 100% sure. There is a reason there was a comment there. Someone thought the following code is not understandable. Now imagine if you have messy code accompanied by a misleading comment. If you do that, i.e. changing code without updating comments, make sure that the next person reading your code is not psychopath. Or if he is, make sure he won’t figure out where you live.
Normalizes Bad Code
Lowering the bar on comment quality is a slippery slope. People tend to use comments as an excuse to commit bad code in the code-base. The common rationalization is: “Oh, we are busy right now. I will fix this mess of a code later. Let’s just put a comment now and we will fix it later when we are less busy.”. Well, over 20 years of work experience, I am still waiting for a so called less busy days to ever show up. The thing is that you are always busy with something. There is always something that gets higher priority. So fix it now.
One counter excuse I heard was that, well, if the messy code is working and not causing problem, that just means that it is lower priority. The problem with this reasoning is time. Certain things are much easier to cure right away. If you let it linger, it becomes much bigger problem to solve. Just like cancer. the longer it is left untreated, it becomes much harder to cure; sadly, at some point not curable at all.
Sometimes the messy code is not fixed, not because it is working. But because it has left there for so long that it has now grown its root in so many different part of the code or even external packages that to fix it you would need to fix and/or change thousands of places. It was a small task at some point, but now, you would need a team of developers to fix it.
When messy code is left there, there is another danger. Something that creeps in so slowly that you won’t even notice it until it is too late. Adding new features becomes harder and harder. You would need to work much harder to keep the same velocity. You grow so much technical debt that at some points throwing the whole thing in trash can and starting anew wouldn’t be such a bad idea anymore. Ask anyone, starting from scratch is really not favored.
If comments normalizes the bad code commit behavior. That is a disaster. I am not saying these based on some theory or just assumption. Unfortunately, seen this in some projects.
How should I decide to comment or not to comment?
There is an easy way to decide weather you should use a comment or not, as explained in the following chart:
First check if this is something that you can address right away. If not, then leave a TODO comment. You really need to have a good reason for not doing it right away. If you are postponing it because you are busy and want to get to another task, or just because you don’t feel like doing it right now, are not good reasons. Have a genuine and valid reason. Something that is not in your control.
Then check if you can rewrite the code in a more self explaining manner. Often times the answer is yes, than no. Also check if the alternative more self explaining version has any performance issue. And By performance I am referring to the code performance. Not that you would need to rework a great portion of the code. Don’t be lazy. If answered yes, then rewrite it and you won’t need to comment any longer.
If you really apply this method and don’t make up excuses for commenting, you would notice that gradually your code becomes more self explaining, your coding quality increases, you are using less comments, you and your teammates are finding bugs much easier and/or fixing bugs easier. Adding new features becomes easier, and overall your progress on the code is faster. If you really apply this method, you would see how few times you really need to comment.
The Winning Bad Comments
The “Clean Code” Book goes on with providing some examples of bad comments. I really suggest that you read that chapter and familiarize yourself. We are going to add some more examples in this section.
Among all the bad comments, funny comments, strange comments that I have seen or heard about in my career, I am going to list some of them here. Of course, I will not copy paste the exact code and comments, just enough to convey the gist of the comment. Of course, I am not going to name names. You know who you are (individuals or companies).
Future Improvement
This was one of the comments:
// Future Improvement and speed up
sleep(some_constant_number)
BTW, the constant number was dividable by 42. It wasn’t just some random number. This codebase was before GitHub becoming popular4. SVN did exists at the time. However, this existed even in the very first version of the code. Code review process was completely a different process back then than what we know today. After all, the very first version of the code looked like having couple of thousands lines of code. So, I can see how it sneaked into the codebase.
The good news is that, no one removed it after all those years. Assuming someone else has also seen this comment in the code-base, I guess they had enough improvement to show to the management that they didn’t need to remove this line.
A follow up funny story is that, I heard about this as a joke may be 5 to 10 years after I saw the actual thing. Well, it was a joke for them; but it was a memory for me.
Comment in a language that I didn’t speak
I was working on a codebase written in FORTRAN, that was giving a whole new meaning to spaghetti code. The comments in that code were all written in a language that I didn’t speak. Not going to say which language, but I just say that it was not in English. Nothing wrong with the comments not written in English. Afterall, the team who had originally written the code, they were all speaking that language. I was the only one who didn’t know their language. So, that’s on me. However, the issue is after I translated the comments, I noticed that it does not at all related to the code. It was like one of them talking about day and the code being about the night. No match at all. So, the code changed, but the comment didn’t. We learned in this document, that that’s one of the reason that comments are frown upon.
Not exactly a comment, but still one of a kind
So, this one is not exactly a comment. But a former colleague of mine told me that he saw the following code in the production code:
print("chicken")
Our guess is that the person who left that there was using the most commonly debugging tools that exists there, that is using “print” statement. But then they forgot to remove it. I do that too. Not the forgetting part; using print-statement for debugging part. I usually use print-statement unless if the issue is more serious. The thing is that this print-chicken was running on the production code. That should tell you how code-review process and quality was. But the more pressing issue was that this print-chicken was in a part of the code which was called a lot. Essentially if there was any change in the state at any part that print-chicken was running.
At some point, internally instead of using the actual unit that was used to measure how long each process takes, people were using how many print-chicken is a process, essentially meaning how many state changes. It became an internal unit of measurement. I heard that later when they changed the code and implemented some sort of a more formal logging mechanism, they even turned the print-chicken to log-chicken.
So, there is a company (I tell you just this much that it is a big company; and don’t bother looking on my resume; They are not listed on my resume; I never worked for them directly); and they are logging thousands, if not millions, of chickens per day. Every now and then that my path as customer crosses with that company, I ask myself: how many chicken has been logged so far?
Checking for a condition
I saw this in an open-source code that is widely used:
! Checking for a condition
IF (condition) THEN
! Commented out code
! Commented out code
! Commented out code
! Commented out code
END IF
That’s some informative comment: “Checking for a condition”. Otherwise, who would have guessed that the next if-statement is checking for a condition. Yes, I am being sarcastic. That’s a terrible comment. Anyway, someone really wanted to check for a condition. But they weren’t doing anything about it. They used to do something about it and call certain subroutines. But apparently that was no longer the case.
BTW, I reported this to the package maintainers. At the time this was not on a GitHub repo. So, you had to send email for changes or bugs to someone.
Again not exactly about comments; But still hilarious
So, in an open-source scientific package I so this:
! Reading user inputs from the file
read (file_unit, *) parameter1
read (file_unit, *) parameter2
...
So far is ok. They are just parsing a text file and reading the values from a text file. but then later in that code (actually the same file), you see:
paramter_1 = some_fixed_number
Well, there was no comments or anything why they are overwriting this specific parameter and ignoring user input on that parameter.
It gets more interesting. There are published scientific papers using this open-source code claiming that changing “Parameter_1” had no effect on the thing that they were studying. No kidding. I would have been more surprised, if they were experiencing any changes in their results using that specific version of the code by changing this parameter.
Again, I reported this to the package maintainers. At the time this was not on a GitHub repo. So, you had to send email for changes or bugs to someone.
References
- Robert C. Martin, “Clean Code: A Handbook of Agile Software Craftsmanship”, ASIN: B001GSTOAM
Footnotes
- So, next time when you are calling out people who say don’t comment and/or be careful with the code documentation, as inexperienced or not having built serious software, remember who you are referring too. Just google these two guys out. ↩︎
- I am wondering, how many would read this sentence in capital letters and then say Moe said to avoid comments at all costs :D. ↩︎
- Mainly because it was very similar, but not exactly the same. So, we couldn’t really exactly use the same stuff. Some changes and tweaks were needed. ↩︎
- I didn’t say GitHub didn’t exist yet. I just said, it was not that popular yet. ↩︎