A number of people have touched on the fact that comments (even 'obvious' ones) provide boundaries, context and intent. I very much agree with this, with a couple of additional comments somewhat particular to embedded development:
- Compared to most user facing development, where probably >75% of code is purely for interaction (and potentially more repetitive, obvious, and readable), a LOT of embedded code is not so readable, and quite often context is key. Good comments (even on apparently obvious code) almost always carry some context (why do this here, and why in this order, why the specific delay before reading the ADC, etc)
- Because almost all the code is in some way business logic, it is definitely easier at times to read the flow of comments, rather than work out directly from the code which register someone is trying to set, and why, or why some seemingly arbitrary value is being incremented (that is actually being read by a parallel task somewhere else)
- As always, good comments are as much for yourself six months from now, as for the guy replacing you 6 years from now. Sometimes, it is just a good way to document your thought process, as well as provide reasonably up to date system documentation, since ACTUAL design documentation almost always gets neglected.
Basically - comment as much as you can, and as much as you need. Try and keep it up to date. It doesn't matter if it's seemingly obvious, or discussing the reasoning behind a particular architectural decision. Nobody I know has ever complained about too many comments, and if anything, more would have always been better.
The article makes some fair points. And once you move beyond the explaining-to-yourself stage, there's yet another reason to have such “useless” comments: quick code navigation.
Finding the place in the code where X is being done would be perfectly feasible by consciously reading the code, but I want to save that energy. Letting my visual cortex pattern-match on a syntax-highlighted comment that looks a certain way is much cheaper and faster and can be done while scrolling through it without stopping. If you can make that comment so it's more useful beyond that, so much the better.
Tricks like that come into play once you're past the language proficiency / commenting policy hurdles and feel the impact of your visual code design on your personal attention and energy budget.
IMO, if I feel the need to add comments to explain code blocks like this:
> // Add a horizontal scroll bar
> hScrollBar = new JScrollBar(scrollBar, HORIZONTAL);
> add(hScrollBar, BorderLayout.SOUTH);
It's a sign I should be writing code that reads more like: > addHorizontalScrollBar()
I can relate to where the author is coming from.
What these comments do is give the code structure, and giving an outsider a better/faster view into the code, when he has no internal model for the library/framework/API/language which helps him recognize the statements (this outsider might be the author himself, or "future me").
Not knowing what these lines do, I can at first glance (i.e. skimming through the code) understand the author's intentions, what each line is responsible for. This is simply reduction of mental load and I even do this just for myself when trying to wrap my head around a new library or language.
On the other hand, if you are writing for a (large) internal codebase, where you need to find a tradeoff between reduction of mental load and bloat, such comments can quickly become a nuisance...
Then again, the cost of useless comment is usually much smaller than the cost of mental load (everyone knows how to ignore comments, unless they fill pages...)
All this being said, I can only recommend "The Art of Readable Code" - Boswell [1].
[1] https://www.oreilly.com/library/view/the-art-of/978144931848...
The big problem with comments is that they need to be maintained. When the code changes, the comments need to change with it.
The never, ever happens consistently.
So soon you have the "man with two watches" problem. The code says one thing, and the comments say another. You could fix it, and sometimes you spend that time, but inevitably you also stop reading the comments, since they're not reliable.
I've never seen this not happen in comment heavy projects.
I spend a lot of time reviewing code, I currently review every line of code for 16 other developers.
Obvious comments are great for code reviews because it's a validation that what you intended to do is what your code actually does.
From the article, the comment about adding a vertical scroll bar allows me to review the code and to check that it does indeed add a vertical scroll bar and not something else.
Did the developer intend to require password lengths of at least 8 characters? A simple comment would tell me what the developer wanted to do and then I can verify that it was done correctly.
When I was doing CS in college, bad commenting was an academic requirement: As in your grade would be worse if you commented appropriately.
Over multiple courses including software engineering, comment quality and or correct use of comments was never in the syllabus.
But in several courses they wanted to see the code heavily commented, to the point where you were just re-writing the code as a comment and getting a green tick instead of a red "more comments!" note. I legitimately believe that my educators just didn't know any better themselves.
These days I live by the mantra: Comment to explain WHY not HOW, since the WHY is lost to time whereas the HOW is often self-descriptive.
PS - [0]Still my favorite comment of all time. I'm still pissed that someone tried to remove it from the article on Wikipedia (in particular as the comment is almost as famous as the code).
[0] https://en.wikipedia.org/wiki/Fast_inverse_square_root#Overv...
Fully agree with the author here. I write comments that "repeat the code" all the time, and I like to read them in other people's code. It allows the reader to quickly skim through large portions of code without having to fully decode each line.
Obviously, I'm not talking about comment like this (which I see all the time):
// adds 1 to x
x += 1;
That is certainly useless, even annoying. But a small comment every 2-3 lines to explain the following 2 to 3 lines is generally very useful.I'm a big fan of Short comments that describe a chunk of code – maybe 3-10 lines. Because a lot of times I don't really want to read all the code, I just want to get a more detailed sense of what the code is doing.
I worked in the Firefox codebase for a while, and what I would have given for a simple comment that describes intentions or results; where instead I had to fire up searchfox.org and make a deep dive into some (equally sparsely commented) functions.
There is some notion here, that these comments help new programmers, but I think as soon as your codebase is sufficiently big, there will be always parts you won't be familiar with, and these comments certainly help you scan over them quickly
I probably end up with numerous "useless" comments in my code.
That's because I write my code's doc string first (or JavaDoc or whatever), then write the body in English comments or pseudocode on rare occasion, then write the code beneath and between the conments that are my English plan.
I will also write additional comments about anything unintuitive, complex or unusual, even slightly, because I know that the code will be read many more times in the upcoming decades. (I have code I wrote in 1994 in production at one company, and another hitting its 20th anniversary this year still in production. Do you even remember libg++? Me neither, but the code still uses it...)
This is also somewhat about language choice. Languages more oriented towards natural language need less commenting. If I were writing C++ or assembler on a regular basis, I would probably be writing a lot of "what" comments.
My favorite comments are actually "what" comments, but that clarify something opaque about the code, e.g.
const R = 6371e3;
const φ1 = lat1 * Math.PI/180;
const φ2 = lat2 * Math.PI/180;
const Δφ = (lat2-lat1) * Math.PI/180;
const Δλ = (lon2-lon1) * Math.PI/180;
const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
Math.cos(φ1) * Math.cos(φ2) *
Math.sin(Δλ/2) * Math.sin(Δλ/2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
const d = R * c;
It's extremely difficult to analyze that and say oh, obviously, that's the haversine distance formula, and the result is the distance in meters, of course. It would be slightly easier in a language with type annotations, but not a bunch easier. You add a simple // haversine distance formula, result is d in meters
and now you can google the wikipedia page to understand the context and history.I sometimes use comments that are nearly as “obvious” as the examples, but more as a human-readable outline of the code block. The point isn’t to provide additional clarity after someone reads the code, but rather to be the first thing someone (especially myself, later) reads when encountering that code block.
When I teach coding, I used to have a similar lesson around commenting code: "don't tell me you're creating a variable. I can read the code. Tell me what the variable is for."
I still mostly abide by that, but I've had an opportunity to write some larger programs for the first time in a few years (a hazard of teaching programming is you find yourself working with pretty small programs), and noticed that the comments started become a part of my conversation with myself. I'd drop in quick reminders for what I intended to do in a function before going moving on to something else. When I came back and then wrote the code corresponding to the comments: well now it's redundant, but it wasn't. I stopped cleaning that stuff up (I'd clean it if I had to present or publish it, of course). The comments kept some context of my thinking when I wrote it, what order I did things in, etc. It would be gibberish for another, but it wasn't for me, especially after a few days, or even longer. (Note: I'm a pretty fast touch-typist, so muttering to myself doesn't invoke much of a productivity cost. I also note that commit messages are another great place to capture that sort of context for yourself, and not using that opportunity is a sin.)
So, I've changed some of my greybeard aphorisms around commenting: "When commenting code, consider the needs of the person who will be maintaining this code. Who will probably be you. Be nice to future you."
For the most part I take no issue w/ the style of comments that act as a statement of intent.
It only becomes a problem when comments are used to paper over the author's own indifference to making the code itself legible, and that's where I expect critiques like this truly come from. Comments without legible code do not help, as the comments are not a proof of correctness or verification that the author's intent has been carried out. You still need to read the code to understand the program.
Code legibility is not unlike legibility in written language. Short sentences and paragraphs, clear transitions, well-defined hierarchy, consistent structure. Say more with less. Comments are often like footnotes: they elaborate upon the author's intent, provide a mental palette cleanser, elaborate on a digression in a way that limits distraction, or occasionally break the fourth wall.
Comments are improper when they try to serve other means. For instance comments about invalid uses of a function/class/etc. when the type system can be used to prevent illegal usages of code. Or when comments are used to explain what is happening in extremely branchy, anti-modular, or otherwise illegible code.
One of my guilty pleasures is writing code comments, even in places where it might be “obvious” about what that block or line is doing. To me, it’s less mentally taxing to read a plain language description of the logic than to decipher that by reading the code. Of course the caveat is that if someone modifies that part of the code and doesn’t update the description, then it could be confusing. I much prefer this to the culture that seems to prevail among some languages (such as Ruby) that the code should be self-documenting.
It is also my experience that writing comments (even the so-called flower boxes, e.g., Javadoc/JSDoc) force me to think about what the code is doing and its readability to future maintainers. If I find myself having to over-explain the block, I might rewrite it or extract it out to a function or class, the name of which summarizes the intent, therefore eliminating the need for the comment.
The more I see people opine on commenting style, the more I want to just spam the "you do you" button and get on with my life.
I have a way that I like to do it. Other people on my team have their own ways. My way is not hurting them. Their way is not hurting me. Either of us trying to impose our way on the other would hurt both of us.
My favorite comments are long winded apologies to my future self, or whoever has to work with the ugly hack I'm putting together to meet a deadline.
How, why, which, where, when, what, who.
The code says how. The commit says what, and where the edited lines were/are in which files, when the edits were committed, and who committed them.
The comments should say why, iff a why is needed.
> I find them useful as I write code because they allow me to state my intention (in plain English), translate it to code, then compare statements and see how well I’ve achieved my goal.
IMO this is exactly what unit tests should be used for. Replace these comments with unit tests and you're doing TDD. The practical difference is by stating your intention as unit tests, you not only verify your initial implementation is correct but also that any future changes remain correct.
I find the choice of the phrase “¿Como te llamas?” fascinating as evidence against “don’t do translation word for word in your head. ” Taken literally, “how (como) you (te) are called (llamas)” has no words in common with “what is your name”. The comments in the code would allow someone with a good Spanish vocabulary to actually translate into fluent English.
I think the bar of usefulness for comments should be pretty low. Most modern IDEs will dim them for you anyway, so it's minimal how visually annoying it is.
The problem is more that you might not have a comment when you need one. There's a lot of times when the author has thought a lot about something and thus understands it, but someone glancing over the code might not.
Example:
def caterpillarMethod(A, s):
n = len(A)
front, total = 0, 0
for back in xrange(n):
while (front < n and total + A[front] <= s):
total += A[front]
front += 1
if total == s:
return True
total -= A[back]
Someone reading this might think it's O(n*2), because there's a loop in a loop and that often makes it so. But if you look closely it isn't. So maybe comment that.Something I don't see mentioned at all is what I call 'div comments' which are solely for chunk organizing. I use something like the following quite a bit (in python/bash):
# =============================================================================
# /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
# =============================================================================
Doesn't give any hints about the codebase but (at least to me) it lets me see related blocks.I always wondered if the "useless comment" comment was really a way of bragging employed by experienced programmers (or their wannabes). Why is it a burden on anyone? Most IDE clearly highlight the comments so you can tune it out. Also, even if it is obvious, at least when a bug presents itself, you don't have to spend much time figuring out the intention of the author and if it is indeed a bug or by design.
These examples aren't great. Functions have names for a reason. Use them. Comments get outdated quickly, people forget/are too lazy to update them. Much less likely in my exp. that someone will not change a fn name if it's behaviour changes.
Comments should be reserved for non-obvious information. Github link, complex mathematics etc. Further, at what point does the relevance of a comment end? This ambiguity doesn't exist with a function.
function addHorizontalScrollbar() {
hScrollBar = new JScrollBar(scrollBar, HORIZONTAL);
add(hScrollBar, BorderLayout.SOUTH);
}
function addVerticalScrollbar() {
vScrollBar = new JScrollBar(JScrollBar.VERTICAL);
add(vScrollBar, BorderLayout.EAST);
}
function initializeScrollbarCaretPositions() {
caretX = 0;
caretY = 0;
caretMemX = null;
}
> I find them useful as I write code because they allow me to state my intention (in plain English)
I have gone back and fourth on comments over the years, but currently I'm working on a solo project which has been in serious development for some time, and using comments in this way is really useful.
Especially because it's a domain I haven't done a ton of work in before, I've found my workflow is often to create a few source files, type out in comments what the component should do, and bit by bit hone in on how that should translate into code.
It's also great for placeholders: if I'm not ready to fill in an implementation yet, I can just type out a lengthy description in the function body, and when I come back a week later I can remember what the intent was.
I generally save comments for WTF code, or to put links that document what's going on. I try to abstract things as a lot of folks are mentioning here, but that just pushes things to another place. Eventually someone is going to need to debug that code. Here's a Puppeteer example, where text is being split into nodes to extract based on line breaks:
/* https://medium.com/@roxeteer/javascript-one-liner-to-get-elements-text-content-without-its-child-nodes-8e59269d1e71 */
return await this.page.$eval(selector, e => {
const s = [].reduce.call(e.childNodes, function(a, b) { return a + (b.nodeType === 3 ? b.textContent : ''); }, '');
return s.replace(/\s+/g,' ').trim();
});
// Add a vertical scroll bar
vScrollBar = new JScrollBar(JScrollBar.VERTICAL);
add(vScrollBar, BorderLayout.EAST);
This actually is helpful if a somewhat long list of components is being added. It makes it easier to find ones way in that list. Kind of like an index. So it really is not a useless comment.But there actually are useless comments. Like when people are told to explain every class member and one ends up with
DatabaseConnection conn; // connection to the database
This really is just clutter and the next problem is that it needs to be updated alongside the code. I once had a colleague advocating adding a comment for every parameter that a method has and then he would himself not update these if parameters were removed. That really is not very good.
For me these comments are useful for two reasons:
1) If you know the author of the code (includes yourself) and you know their comments are a good indication of the code, you just read them and move along. No need to understand what they do.
2) If you don't know the author or you know their comments are often out of date (which you can check with git blame but let's ignore that) the comments tells you what the original intention was, and with an already mental model its easier to read code and understand what it's doing, even if it contains mistakes (in the worst case the code will have nothing to do, so it will be like if you had no comment).
I wrote obvious comments to obvious code. No one else looks at my code but I do, a lot. The result is easy navigation of many many lines of code. The comments act as an index and summary to each section.
When it comes to comments, be verbose!
I always try to write a comment that say "why" the following code is needed or what concept it implements rather than what it does in details.
I would do
// We allow scrolling in two directions
hScrollBar = new JScrollBar(scrollBar, HORIZONTAL);
add(hScrollBar, BorderLayout.SOUTH);
vScrollBar = new JScrollBar(JScrollBar.VERTICAL);
add(vScrollBar, BorderLayout.EAST);
caretX = 0;
caretY = 0;
caretMemX = null;
(I don't have much inspiration in this specific example)I agree in principle. If it takes more than more than a second to grok what a particular bit of code is doing, it should have a comment (or be extracted into a method).
However, in my experience, it's common for either:
1. Code to get changed, but the relevant comments are unchanged, or
2. Comments that are just as hard to understand as the code
In both cases, it's even harder to understand the comment+code than if there was no comment at all
I write comments based on what I expect I will need to know if I close the editor and don’t look at the code again for a couple years and will need to jump back into it as quickly as possible. That usually means I don’t want to waste the time of future me reconstructing what the code denotes if I could just write it down in a comment in he first place.
I quite often use region/endregion comments to group methods of an interface being implemented, especially if a class implements multiple interfaces. The advantage of those is that an IDE/editor can collapse them and it is easier to see hat methods belong to which interfaces.
Article mentions my preferred take: stating my intention to help keep me honest on what I am trying to achieve.
Also: they function like an anchor tag. If you are spelunking a new code base for a specific functional area, a search in plain English would let you jump to the right spot more quickly.
This text reminds me of the fact that value judgements are personal and subjective. So, one man's benefit is another man's cost.
To make matters worse, it's hard to do math with these things, thus net benefit can't possibly be calculated.
99% of code is internal and something noone unexperienced will look at.
If you're writing code for a tutorial for newbies then yeah, it makes sense to add obvious comments. But that's really it. The author is overstating his case.
A tangential point is that the syntax coloring configuration in the editor should emphasize comments.
If comments are de-emphasized (e.g. grayed out compared to code) you will get bad comments and comments out of sync with the code.
I think it's stupid when people say they don't think code comments are good or necessary. It's a weirdly religious debate and frankly I think having a ton of code comments is great. Some of my closest friends think that all comments are absolutely unnecessary. We didn't work in the same code repos.
I think 2 IDE features would make things easier for everyone:
1) have an option to remove code comments from view if you don't like them
2) tie a code comment to a piece of code and enforce it. If you change that piece of code, you should be forced to update and tied comments, or force to check that the comment is still correct. And have the fact that you approve a comment should be a part of the check in, so people can trace it.
I’m on the same page. Just look at the given example. Does it look wasteful to say that you’re adding a vertical bar when you have the following line of code?:
Perhaps. But the comment is making a lot more than simply describing what’s below of it. The comment is doing the following things:- It’s creating a visual boundary that aids to the readability of the code. It adds context within a large set of instructions.
- It’s providing context that might not be there for the person who is reading the code. Just because you think the name of that function and what you’re passing into it clearly describes the instruction, doesn’t mean that everyone else does. At least not in a snap. The comment helps to reduce the cognitive load of reading the code because it’s explaining the instruction in plain english.
- The comment itself could be part of a larger narrative that is trying to explain what that file is doing. It’s not there to make the obvious more obvious. It’s there to make the whole file obvious which is evidently important to write readable code.
Look. I know there are purists that get offended with obvious code comments. But you cannot expect everyone to have the same proficiency you do. Writing good code, also means writing code that a newbie can at least comprehend. And sometimes that means explaining in plain english what could be already obvious to you.
People like to think they are writing code like prose that is delightful to the reader, but many times are just writing reader hostile code.
Write code focusing on clarity. Not elegance by obscurity. Make it clear, add structure, add visual boundaries. Ask yourself if what you think is obvious is obvious to everyone. If in doubt explain it with a comment. I’ll rather see an obvious comment and say “well that’s obvious” than spending valuable time trying to understand what certain piece of code is doing.