If somebody says a comment isn’t adding any value, I would ask: to whom?
Personally, I’ve never liked the advice that writing obvious comments is bad practice—probably because I write obvious comments all the time.
Jim showed off some examples of “code comments that are at the same level of fidelity as the code itself.” Those are the hardest calls with code comments.
// this function adds two numbers
function add(a, b) {
return a + b;
}
Easy to point at that and call it not useful. I tend not to leave this type of comment, but it’s fair play for Jim to question that. Comments can be used for a wide swath of people whom may at some point interact with that code, so why gate-keep it?
[…] comments can serve a very different purpose when they’re being read vs. when they’re being written. Those are almost two different kinds of activities.
I’d add they serve a different purpose when re-visiting old code vs actively working. Also different when you’re trying to code review versus directly contribute.
I always hated when anyone pointed that I comment too much. My goal is to write a code that anyone with any skill can read, understand and/or learn from. When I leave a project I want to leave it in a state that a junior dev can get into and figure it out.
It’s easy to read a comment with 15 years of experience, but what I found is that the new people need guidance. Those obvious comments saves a lot of frustration.
If you have a complicated conditional,
if (A && B && (C || !D)) { ...
, you might add a comment saying// check <complex property> of <thing>
. Oftentimes this is a signal that it makes sense to abstract the logic into a function/method;thingHasComplexProperty = (A, B, C, D) => (A && B && (C || !D))
. This way your conditional readsif(thingHasComplexProperty(A, B, C, D)) {...
, removing the need for the comment (alongside other potential benefits).Something like
add(a: number, b:number): number
is perfectly self-explanatory in Typescript – in JS, you may need more verbosity, but thenaddNumbers(a,b)
is much better, since this makes it obvious at call-sites, so that still doesn’t warrant a comment.My rule of thumb for inline code comments, is they should not explain what the code does – you can read well-written code to see what it does. If I write an inline code comment, it’s to explain why – not what. (Unless the code is too complex or unreadable – in which case, that really calls for refactoring, not comments.)
I take the same approach with commit logs: never explain what you changed – the diff will reveal what; instead, explain why you changed it.
I am generous with “why” comments, so it’s not that I’m trying to keep the number of lines low – it’s that, if I add comments, they should add to the information that is already present. If you write comments that merely repeat other information, you only diffuse or confuse the information; you’re teaching the reader to ignore your comments.
Years ago I proposed (partially in jest) that a metric could be put on “readability” by counting the number of hiccups or hitches in the flow of someone reading the code– that is to count each ever-so-brief look-back or pause where the reader rechecks or double-checks a line to confirm that it was understood correctly. The fewer times you have to do that the more readable the code. When reading code with embedded comments, one could make the case that jumping back and forth between // lines that are clearly comments associated with segments of code and uncommented segments that are self-documenting is inherently less readable because of it causes hitches in the flow. I’m not saying it is good or bad or whether I would like it or not, but I am saying that a case can be made.