In the “Why” vein, some of the most important comments are “Why I made the compromises I made” aka “Why this looks dumb but is actually for the best” comments.<p>They can prevent someone, including myself, from undergoing a timely rewrite of strange or bad looking code before inevitably hitting the same wall I hit previously.
The advice in 'Replace What Comments With Names' section was just talked about recently here: <a href="https://news.ycombinator.com/item?id=37517329">https://news.ycombinator.com/item?id=37517329</a> in an article I agree with 'Linear Code Is More Readable'.<p>If you're going to reuse those little tiny functionettes, then sure, it might be worth doing, but to do it for readability is misguided. Comments are a perfectly reasonable way of indicating logical blocks within code.
100% agree with most of this, but I think the why can be dug into a little deeper. Under why comments I find they fit into two categories:<p>1) Why does the code exhibit behavior X? (~80%)<p>2) Why does the code do X this way? (~20%)<p>1 is usually a customer facing quirk which should be written down somewhere, but preferably not in the code directly. This stuff fits extremely well in tests which exercise the behavior ("why does a user get an ID before the creation of a ticket?"), in reference docs ("why country appears 3 times in this API schema") or in a glossary (e.g. a quirks section under the "admin user" wiki page). These explanations will get more eyes on them this way, will be more likely to be kept up to date and will be available to non developers.<p>2 should not be non-existent but should be rare. In practice I find 2s are almost entirely absent from most code bases because to the person writing the code it is obvious.<p>For 2, because of this, I find it's better to get somebody else to ask why and use answers to the whys on pull requests to write those comments: <a href="https://hitchdev.com/approach/communal-commenting/" rel="nofollow noreferrer">https://hitchdev.com/approach/communal-commenting/</a>
Missing is one other style of comment: how to use this API. This is not targeted at someone understanding or maintaining the code, but someone outside who just knows (or suspects) they want to use your API without understanding it. While this need not be with the code it generally is better that way because tools can extract information from the code (the comment is before the function foo, therefore it must be about foo, foo takes some parameters with some types - we can link to the documentation for those types...).<p>This style of comment is only needed if you expect your code to have users who are external and thus don't want to look into the details.
Tangential, but see:<p><a href="https://news.ycombinator.com/item?id=37583258">https://news.ycombinator.com/item?id=37583258</a><p>Explaining "why" is often (revealing) more about how the programmer is
thinking at that moment. It reveals hidden or ineffable knowledge
about how the coder arrived at that point/design, and may reveal
intent not explicit in the code itself.<p>Mismatches between the declarative and imperative have often been
where I've found bugs. Especially in my own code when trying to
explain it to myself in a comment opens my eyes to an error.<p>Those "why" comments are our stories about our code.
I typically write comments for "why" rather than "how". Or if I have to make what appears to be a weird hack or decision I put that too.<p>Another thing I really like to do is put github issues as comments if I am having to do some weird workaround in some API/library that I found from a github issue - i'll put the github issue URL so that way it is easy to see the latest update from that library later on to see if the workaround is no longer needed.
The fundamental issue with comments in programming is that they're part of the code, which is a ridiculous hack that somehow survives unquestioned. This is not how comments work in Google Docs, Microsoft Word, etc.. Maybe the idea of implementing comments as a greyed out part of the main text did not occur to the designers of these apps?
There is also the comments about why something commented out exists. Don't make your fellow developers (including future self) to figure it out again.<p>//// These lines are a very simple way to enable feature X on your machine:<p>// obscure.thing=false<p>// someVar = "probablyAthing";
You all would hate my code, and that's okay. Why? Because I do everything that is suggested, save one: I leave <i>what</i> comments in.<p>For some reason, it is easier and quicker for me to understand English prose than code, even if the code is simple. That includes checking the actual code after reading the comment to see if it matches; having a target for the code makes it orders of magnitude easier to read for me.<p>That said, I still weirdly find value in <i>what</i> comments. Even some of the simplest ones communicate intent for me.<p>For example, I have many comments that take one of the following forms:<p><pre><code> // Cache this.
// Get the <item>.
</code></pre>
These are the exact comments that people hate so much, but I like them because they communicate these things to me:<p>* The item is gotten for efficiency reasons. This means that I should check that it really is more efficient if something is slow.<p>* More importantly, the item is expected to <i>not change</i>, so if I'm digging aground for a bug, I should check that the item actually does not change.<p>So these "useless" comments actually help me.<p>In addition, the fear that they will go out-of-date is less of a problem for me because I have a strict habit of updating comments with code.<p>Now, I don't suggest that everybody do what I do; I suggest the opposite, in fact. But I work alone, so I can do things that were ideal for myself.
An interesting go-ish thing to do regarding: """Now, DownloadAndVerifyThing is shorter, contains less state, and is more obviously a composition of several tasks."""<p>...I've experimented with "convert a long sequential, independent function into several internal anonymous functions" (ie: similar to IIFE in javascript).<p>This generally prevents (or contains) variable leakage and prevents (or contains) "complexity leakage".<p>In their example: `DownloadAndVerifyThing(...) { ... }`, those functions could be defined internal to the `DownloadAndVerifyThing` function, which is kindof a further form of comment: "thou shalt not be using these weird functions outside of this particular function which does the downloading and verifying..."<p>Even if it's done not in a function but in an anonymous block, "trapping" any state leakage or side-effects is nice for complexity reduction.<p>Example:<p><pre><code> func Foo() bar {
{
x := 1
y := 2
...lots of math, etc...
}
abc := 123
}
</code></pre>
...you're not polluting the function internally with a lot of extra variables hanging around, which makes the inevitable refactoring "more clean" as you know at least the code block can be extracted independently w/o impacting anything _after_ it (although you still have to be a little careful with the "before" and "ordering" portion of it).
Tangential but I will say that c# is a great multi-paradigm language with terrible code comment culture that still uses xml-based comments, ugh it drives me crazy. I've even looked into figuring out how to get the compiler to auto transform javadoc-style or implicit-style comments into the structured format it expects, but it's been tricky. I find this verbosity with the xml markup makes it more difficult to read as a human and discourages good comments.
i wonder... things like this are known (mostly from trial and error bit not only) for 50-60+ years.. why they are not studied?<p>and every new kid on the block has to find-out/invent them ?
I'd like to add another comment type to this list, which is searchable #topics and alternative procedure names.<p>For example, if there's a feature around replies, I may put #replies in the key places in the code. If some code takes part in generating replies.html, I might put "#replies.html" as a comment.<p>A lot of my procedures have comments with alternative names aliased underneath:<p><pre><code> sub SqliteQueryHashRef { # $query, @queryParams; calls sqlite with query, and returns result as array of hashrefs
#sub SqliteGetHash {
#sub SqliteGetHashRef {
#sub SqliteGetQueryHashRef {
#sub SqliteGetQuery {
#sub GetQuery {
#sub GetQueryAsHash {
#sub GetQueryAsArray {
#sub GetQueryAsArrayOfHashRefs {
</code></pre>
Each of these represents a time in the past when I went into the global find tool and searched for e.g. "GetQuery ", didn't find anything, and then eventually tracked down this procedure.<p>BTW, if you only put a space after the procedure name in its definition, its much easier to search for.
I like the idea of comments being impossible and one acts with that in mind. Along with the one about thinking the next person to view your code is a psychopath who knows where you live. Holding those 2 things in mind, you really can have your cake at eat it (too), you can have clean expressive code that covers a lot of the “why” without comments littering the screen.<p>How are you going to make the code itself scream of its “how and why”? Then failing that you can put a comment if you must.<p>I have worked with codebase with incredible comments. Changing the code was really hard and laborious and far from a joy to work with. When PRs become back and forth about how to change the wordings of the comments in the code, it is soul destroying, it becomes very time consuming. Like writing a joint novel at the same time as writing the code. Some people like it that way and each to their own, I know I can’t convince them.