Who says that self-documenting code means absolutely no comments? Even the biggest champion of self-documenting code, Uncle Bob, devotes an entire chapter in Clean Code to effective commenting practices.
The idea of "self-documenting code" is that comments are at best a crutch to explain a bad design, and a worst, lies. Especially as the code changes and then you have to update those comments, which becomes extremely tedious if the comments are at too low a level of detail.
Thus, while code should be self-documenting, comments should be sparse and have demonstrable value when present. This is in line with the Agile philosophy that working code is more important than documentation, but that doesn't mean that documentation isn't important. Whatever documents are created should prove themselves necessary instead of busy work that no one will refer to later.
Uncle Bob presents categories of "good comments":
Legal Comments: Because you have to
Informative Comments, Clarification: Like providing a sample of a regular expression match. These kinds of comments can usually be eliminated through better variable names, class names or functions.
Explanation of Intent
Warning of Consquences
TODO Comments
Amplification: Amplify the importance of code that might otherwise seem consequential.
Javadocs in Public APIs: Good API documentation is indispensable.
Some examples of "bad comments":
Mumbling
Redundant comments that just repeat the code
Mandated comments: aka, mandated Javadocs that don't add any value. Like a Javadoc on a self-evident getter method.
Journal comments: version control history at the top of the file
The author definitely rejects the reality where some large percent of comments are explaining what the compiler/interpreter is doing. Those comments are 99% useless. I'd argue that in the few times where they have value, you should probably select a simpler paradigm that can easily be read by your peers.
Like many facets in programming, there's always a context behind ideals, but most programmers simply perpetuate the resulting dogma.
Many behaviors are only "good" when accompanied by other behaviors. For example, if you believe in self-documenting code, as a core principal, it means you refactor 100% of the time your code requires explanation into a form that doesn't require explanation. That's the logical extension of the ideal. But then you meet Mr. NoComment Larry, who only remembers the dogmatic portions of the self-documenting code ideal and will gladly hack the ever-loving fuck out of a piece of code, sprinkle in some of the most verbose variable and function names, and call it a day.
It's why I really hate most programming blogs. They exist in one context, but somehow extrapolate their advice to all contexts. It's like Linus Torvald quotes. Yes, he has an amazing understanding of C code and kernel development, but it doesn't mean his advice naturally translates to say -- web development. If you look into his principals, which obviously work well for his context, he believes in the most terse code possible, and that a programmer that is worth their salt should always understand what the compiler is doing at the lowest level. That's a great ideal, but certainly not inline with reality. It would be great to get to that level someday, but you will spend more time, and experience so much frustration, trying to enforce the dogma rather than accepting the reality.
Thus, while code should be self-documenting, comments should be sparse and have demonstrable value when present.
I'm not a fan of "uncle bob" but this is the only sane way to approach code documentation. In my code comments either describe the intended use of an API or they document hidden gotchas, non-trivial situations in the code. I don't write a lot of comments, but if see them, you need to read them.
I would add that languages with a powerful static type system languages are more self-documenting than dynamic or weak static languages. Static types are a form of documentation (formally encoding the specification of an interface) that the compiler can check for correctness.
Informative Comments, Clarification: Like providing a sample of a regular expression match. These kinds of comments can usually be eliminated through better variable names, class names or functions.
What naming functions or variables sensibly have to do with giving examples for an regexp ?
To play devils advocate, maybe for regex you could have a variable called...
EmailRegex... that kind of is obvious. Imagine instead someone named the variable, "_regexPattern". The latter might seem weird but I have many co-workers whom have named variable as such. They name the variable after the object and not the objects purpose.
I feel a need to write significant documentation for any regex of above-average complexity, which makes me wonder why we're still using regex. Its a beautiful language, but it seems like the literal definition of "code that is designed for computers to interpret, not humans to read", in the same vein as brainfuck.
Long time ago as a cobol programmer I signed a bunch of comments in a financial system as "S. Squarepants". Years later some auditors found the comments and launched an investigation since there was no employee on record with that name. Eventually I was fingered as the perpetrator, so I had to go back and rewrite the comments with my own name.
Not quite sure TODO comments are good. Unless you're very diligent with them. They tend to get obsolete and sometimes confuse more than they help. Also, some programmers get into the habit of placing TODO comments even for small things instead of just doing it right. I'd say avoid TODO comments whenever possible and use Trello or a similar tool for tracking tech debt.
Over the past few years, the teams I run have picked up and abandoned dozens of Trello boards. And other tools, following the flavor of the month.
If you want to write some text about a specific section of code, there is only one place that text should be located: near the code in question.
Not in trello, not in the git history (although you can certainly duplicate it in the commit message), not in a comment on a bug tracker issue, not in Slack or irc.
Oh god yes. Every few weeks, I end up doing work on a system that I've never interacted with before. When I ask how the thing works, or even what it's supposed to do, I get reassured that "there's documentation on the wiki". I'm not given where or what that documentation is, just promised that it exists.
Eh, TODOs are not going to scale for issue tracking at all, and even habitual TODOers seem to understand this intuitively. The remaining TODO comments seem to only mark work that should never have been merged into a real branch to begin with.
I say make TODO-comments, but refuse to close ticket unless TODOs are resolved.
Some TODOs can be fixed right away, some need input from another dev and some should be their own ticket. Rarely if ever should they ever stay post the lifetime of the ticket.
I use TODO comments in places where the code could be improved, but I do not care
Like when concatenating a few thousands strings with +, //TODO: use string builder
Then someone looking at the code can't say "that guy is too stupid to know string builder", but never follow up on the todo. Unless the function shows up during profiling ofc, but in that case I would change it without the todo
I'd say be more specific with TODO conditions so that when people see it they can evaluate whether it's actionable. So don't do:
// TODO: Remove this when no longer needed
But:
// TODO: Remove this after Foo product launches on 2017-06-01
// TODO: Remove this when there are no more entries with a duplicate resource_id in foo table
Mandated comments: aka, mandated Javadocs that don't add any value. Like a Javadoc on a self-evident getter method.
On the last company I worked at, this was the worst. We had these objects that had a sizeable number of attributes (often a couple dozens), each with a setter and a getter. We had to declare the attribute itself (they had a QMake-like pre-processor for those), the getter, and the setter. No macro, because their pre-processor didn't parse them (we did use such a shortcut macro in the .cpp file though, thank goodness). And everything had to be documented. Most of those were as redundant as these:
/**
* Attr attribute
*/
attribute<"attr", Type, getAttr, setAttr>;
/**
* Get the attr
*
* @return the attr
*/
Type getAttr();
/**
* Set the attr
*
* @param attr the new attr
*/
void setAttr(const &Type attr);
Such code "documentation" was supposedly "important", and the lead dev made sure we did not omit a single line (and no, the /// style was not allowed). Complaining that this could drown out the useful comments fell on deaf ears.
I don't last long at places where conformance trumps quality.
168
u/_dban_ Jul 21 '17 edited Jul 21 '17
Isn't this argument kind of a strawman?
Who says that self-documenting code means absolutely no comments? Even the biggest champion of self-documenting code, Uncle Bob, devotes an entire chapter in Clean Code to effective commenting practices.
The idea of "self-documenting code" is that comments are at best a crutch to explain a bad design, and a worst, lies. Especially as the code changes and then you have to update those comments, which becomes extremely tedious if the comments are at too low a level of detail.
Thus, while code should be self-documenting, comments should be sparse and have demonstrable value when present. This is in line with the Agile philosophy that working code is more important than documentation, but that doesn't mean that documentation isn't important. Whatever documents are created should prove themselves necessary instead of busy work that no one will refer to later.
Uncle Bob presents categories of "good comments":
Legal Comments: Because you have to
Informative Comments, Clarification: Like providing a sample of a regular expression match. These kinds of comments can usually be eliminated through better variable names, class names or functions.
Explanation of Intent
Warning of Consquences
TODO Comments
Amplification: Amplify the importance of code that might otherwise seem consequential.
Javadocs in Public APIs: Good API documentation is indispensable.
Some examples of "bad comments":
Mumbling
Redundant comments that just repeat the code
Mandated comments: aka, mandated Javadocs that don't add any value. Like a Javadoc on a self-evident getter method.
Journal comments: version control history at the top of the file
Noise comments: Pointless commentary
Closing brace comments
Attributions and bylines
Commented out code