Previous: Advanced metaprogramming in C
It's often said that when writing comments you should document intent rather than algorithm.
However, I think lot of programmers haven't really grasped the maxim. Therefore, I was trying to come up with a minimal use case, an example that would illustrate, in very simple and easy to remember way, why that is the case.
Imagine you are debugging an application written by someone else. You have little understanding of how it works, what are the data structures or algorithms and so on.
When you look at the block of code that is the likely culprit, there are two lines like this:
/* Increment orderid. */
orderid++;
Ok, so some kind of order ID is being incremented here. Everything works as expected, right?
Well, imagine that the code was written in a slightly different way:
/* Get next order ID. */
orderid++;
Aha. That makes it more interesting. Is the next order ID the one with ID+1? Maybe the orders are ordered in decreasing sequence and the code should have been:
/* Get next order ID. */
orderid--;
You investigate some more and yes, it turns out that while the order IDs are increasing there may be holes in the sequence because of cancelled orders.
And here's the fix:
/* Get next order ID. */
while(1) {
orderid++;
if(is_valid_order(orderid))
break;
}
The example above was deliberately trivial. It may seem at first glance that the different between "increment" and "get next" is insignificant. However, once the code grows sufficiently complex, such clarity in expressing the intent can make a world of difference.
Martin Sústrik, August 3rd, 2015
Previous: Advanced metaprogramming in C
1. I used to feel superior to that classic "increment i" comment as well, but I stopped when I started programming in this little VM assembly and found myself doing it. Since it doesn't have structured loop syntax, I often find myself using "increment" comments to separate loop body from loop update.
More generally, I started looking at the code at work (not the greatest level of workmanship) and I noticed the same tendency: the author of new code would use comments as section headings, with the goal of having something in the comment color punctuate sections and segment distinct cognitive morsels for reading. Unfortunately as new changes were added the rhythm and tempo of "delimiter comments" would be destroyed. Delimiter comments don't play well with our tendency to minimize diffs for new features. If later updates would delete and reinsert comments to restore the rhythm, that would be helpful. But people are irrationally afraid (or rationally apathetic) to modify comments.
I've been experimenting for some time with two-tone comments, to distinguish section headers from details: http://akkartik.name/post/2012-11-24-18-10-36-soc. I find them useful, but they don't provide nested delimiters.
—-
2. Let me show you a slightly more complex loop example from my VM:
How would you apply your idea in this instance? Maybe I shouldn't bother mentioning the wrap and just say, "mark this slot [of the circular buffer] as empty".
Ooh, maybe I should replace the comments at least in basic loops with a local continue: label that the body can jump to to continue. I tend to do that when I need it, but it also makes a good section heading.
I am also using comments as delimiters, but I usually find that if a piece of code deserves its own section there's also a sentence or two to be said about its intent.
As for your example code I don't speak the language so it's hard to tell but two generic observations come to mind:
1. None of the comments says what the code is supposed to do. Not knowing the syntax, I have no idea what it does, which is, in its own way, a documentation failure.
2. Two comments for 5 lines of code seems excessive. The code doesn't look so tricky that the programmer skilled in the language would not be able to understand what it does by simply checking the code. But maybe I am wrong.
It's a fragment at the end of a routine to read a value from a circular buffer. It was interesting to go back to it because I wrote it early in my design of the VM, when I myself wasn't fluent in the language I was creating, so I was labeling short chunks of lines with what they do (often in C, though you don't see that here). Over time the #comments/line went down.
Here's how your post got me to update some stale comments: https://github.com/akkartik/mu/commit/c79f434177. Thanks!
You're right that the sections have intent. But the effort of phrasing that intent is the death-by-thousand-cuts reason they don't get written.
Paradoxically, this thread has me wondering if I should stifle the urge to write certain kinds of comments, given their almost inevitable tendency to get in the way. Instead of text, I might try just delimiter comments like "# —" while writing. And I might consider deleting them before committing. Like commented-out code, they might be too closely tied to the process of writing and not useful to readers. They also won't create false complacency that "the code is well-commented".
Smalltalkers say section comments are code smell. Method with section comments must be divided into several private submethods (ironically enough there are no private methods in Smalltalk but that's other topic.)
About expressing intentions: I suppose it is better to cram intention info into procedure/method names and regard comments code smell (except attention marks and temporarily commented out code.)
void move_to_next_order() { orderid++; }
I personally hate when people do that. It results in a lot of small functions just waiting for someone else to invoke them and turn a linear control flow into a complex call graph.
I like the ""# —" idea. I was thinking of using that several times but was to cowardly to actually do it :)
Another option is to define functions (get_next_orderID in this case), even for single statements. Not only this will be more abstract, also self-documenting.
Yes. But it only works until you need a whole sentence (or two) to describe the intent.
You're missing a close-paren on "if(is_valid_order(orderid)"
Fixed. Thanks for spotting it!
Post preview:
Close preview