Live data from Hacker News

Maybe comments should explain 'what' (2017)

hillelwayne.com

141–150 of 212 posts

Re: Maybe comments should explain 'what' (2017)

#141
post #130
post #50

Earlier quoted context omitted.

> That's explaining "what" but also implicitly "why" - because that's how double-entry works and that's the tolerance banks allow for settlement delays. You can't really extract that into a method name without it becoming absurd. That's why I've also started to explicitly decompose constants if possible. Something like `ageAlertThresholdHours = backupIntervalHours + approxBackupDurationHours + wiggleRoomHours`. Sure,…

I don't necessarily disagree with providing context, but my concern is that comments eventually lie. If the business rule evolves (say the window moves to 5 days) the comment becomes a liability the moment someone updates the code but forgets the prose. The comment also leaves me with more questions: how do you handle multiple identical amounts in that window? I would still have to read the implementation to be sure.…

This however misses an important point: 3 is not in our control. 3 in general is controlled by math-people, and that 3 in particular is probably in the hands of a legal/regulation department. That's a much more important information to highlight.

For example, at my last job, we shoved all constants managed by the balancing teams into a static class called BalancingTeam, to make it obvious that these values are not in our control. Tests, if (big-if) written, should revolve around the constants to not be brittle.

Re: Maybe comments should explain 'what' (2017)

#142

Earlier quoted context omitted.

const int backupIntervalHours = 24 const int approxBackupDurationHours = 2 const int wiggleRoomHours = 2 const int ageAlertThresholdHours = backupIntervalHours + approxBackupDurationHours + wiggleRoomHours; static_assert(28 == ageAlertThresholdHours); It's a shame more languages don't have static asserts... faking it with mismatched dimensions of array literal/duplicate keys in map literals is way too ugly and distra…

Mmm... ageAlertThresholdHours = 24 + // backup interval 2 + // approx backup duration 2; // "wiggle room" No static assert needed, no need to pre-compute the total the first time, and no need to use identifiers like `approxBackupDurationHours`, the cognitive override about the possibility of colliding with other stuff that's in scope, or the superfluous/verbose variable declaration preamble.

I'm a believer in restricting the scope of definitions as much as possible, and like programming languages that allows creating local bindings for creating another.

For example:

    local
        val backupIntervalHours = 24
        val approxBackupDurationHours = 2
        val wiggleRoomHours = 2
    in
    val ageAlertThresholdHours = backupIntervalHours + approxBackupDurationHours + wiggleRoomHours
    end
Then it's easier to document what components a constant is composed of using code without introducing unnecessary bindings in the scope of the relevant variable. Sure constants are just data, but the first questions that pops into my head when seeing something in unfamiliar code is "What is the purpose of this?", and the smaller the scope, the faster it can be discarded.

Re: Maybe comments should explain 'what' (2017)

#143

Earlier quoted context omitted.

Splitting example is way too much indirection, but capturing what the code does in the code itself is a preference for me. In any high level language don't know why the middleground wasn't explored: var hasSymbol = getSymbol(symbolName) != null var replacementPending = !alreadyReplaced.contains(symbolName) if(hasSymbol && replacementPending){ alreadyReplaced.add(symbolName); stringToReplace = stringToReplace.replace(…

As for the comments, I would probably write it like this: /* Symbol actually exists */ if ((NULL != getSymbol (symbolName) /* and still to be added */ && (!alreadyReplaced.contains (symbolName)) { ... Although in this specific case the comments seem like noise to me. > Technically this performs worse because you lose short-circuiting Not really, because optimizing compilers are a thing, when this thing is parsed into…

The compiler would have to determine that these are pure calls which I wouldn't rely on if performance actually matters

I just tested a recent gcc at -O2 with a contrived example using strings in an unordered_set: a look-up always occurs if not relying on short-circuiting

Re: Maybe comments should explain 'what' (2017)

#144
post #2

I feel like no one serious uses the uncle Bob style of programming anymore (where each line is extracted into its own method). This was a thing for a while but anyone who's tried to fix bugs in a codebase like that knows exactly what this article is talking about. It's a constant frustration of pressing the "go to definition" key over and over, and going back and forth between separate pieces that run in sequence. I…

For an example of what happens when he runs into a real programmer see: https://github.com/johnousterhout/aposd-vs-clean-code _A Philosophy of Software Design_ is an amazing and under-rated book: https://www.goodreads.com/en/book/show/39996759-a-philosophy... and one which I highly recommend and which markedly improved my code --- the other book made me question my boss's competence when it showed up on his desk, but…

That entire conversation on comments is just wildly insane. Uncle Bob outright admits that he couldn't understand the code he had written when he looked back on it for the discussion, which should be an automatic failure. But he tries to justify the failure as merely the algorithm just being sooooo complex there's no way it can be done simply. (Which, compared to the numerics routines I've been staring out, no, this is among the easiest kind of algorithm to understand)

Re: Maybe comments should explain 'what' (2017)

#145
post #2

I feel like no one serious uses the uncle Bob style of programming anymore (where each line is extracted into its own method). This was a thing for a while but anyone who's tried to fix bugs in a codebase like that knows exactly what this article is talking about. It's a constant frustration of pressing the "go to definition" key over and over, and going back and forth between separate pieces that run in sequence. I…

Great, that's exactly how I feel with any style that demands "each class in its own file" or "each function in its own file" or whatever. I'd rather have everything I need in front of my eyes as much as possible, rather than have it all over the place just to conform with an arbitrary requirement. I said this at a company I worked and got made fun of because "it's so much more organized". My take away is that the ave…

If those demands made any sense they would be enforced by the languages themselves. It's mostly a way of claiming to be productive by renaming constants and moving code around.

Re: Maybe comments should explain 'what' (2017)

#146
There are five canonical questions: What, When, Where, Why, and How.

"When" is occasionally a good question to answer in a comment, e.g. for an interrupt handler, and "Where" is also occasionally a good thing to answer, e.g. "this code is only executed on ARM systems."

The other three questions typically form a hierarchy: Why -> What -> How.

A simplistic google shows that "code comments" are next to "what" and "how" at about the same frequency as they are next to "why" and "what."

This makes some amount of sense, when you consider the usual context. "Why" is often an (assumed) obvious unstated business reason, "What" is a thing done in support of that reason, and "How" is the mechanics of doing the thing.

But with multiple levels of abstraction, _maybe_ the "What" inside the hierarchy remains a "What" to the level above it, but becomes a "Why" to the next level of "What" in the hierarchy. Or maybe the "How" at the end of the hierarchy remains a "How" to the level above it but becomes a "What" to a new "How" level below it.

Is it:

Why -> What/Why -> What/Why -> What/Why -> What -> How

or

Why -> What -> How/What -> How/What -> How/What -> How

In many cases the intermediate nodes in this graph could be legitimately viewed as either What/Why or as How/What, depending on your viewpoint, which could partly depend on which code you read first.

In any case, there are a few hierarchies with final "Hows" that absolutely beg for comments (Carmack's famous inverse square root comes to mind) but in most problem domains that don't involve knowledge across system boundaries (e.g. cache optimization, atomic operations, etc.), the final "How" is almost always adequately explained by the code, _if_ the reader understands the immediately preceding "What."

If I see a function "BackupDatabase()" then I'm pretty sure I already know both "Why" and "What" at the highest levels. "How" I backup the database might be obvious once I am reading inside the function, or the code might be opaque enough that a particular set of lines requires explanation. You could view that explanation as part of "How" the database is backed up, or you could view that explanation as "What" the next few lines of code are doing.

Again, this viewpoint might even partly depend on where you started. If you are dumped inside the function by a debugger, your question might be "What the heck is this code doing here?" but if you are reading the code semi-linearly in an editor, you might wonder "How is BackupDatabase() implemented?"

Re: Maybe comments should explain 'what' (2017)

#147

[flagged]

> The "what" vs "why" distinction breaks down when your code encodes domain knowledge that readers can't infer from context.

Yes, there are multiples levels of knowledge, and the required level of commenting depends on the minimum knowledge expected of a reader in each of several dimensions.

In point of fact, the only thing that almost always can do without documentation is a different question, "How."

Re: Maybe comments should explain 'what' (2017)

#148
post #142

Earlier quoted context omitted.

Mmm... ageAlertThresholdHours = 24 + // backup interval 2 + // approx backup duration 2; // "wiggle room" No static assert needed, no need to pre-compute the total the first time, and no need to use identifiers like `approxBackupDurationHours`, the cognitive override about the possibility of colliding with other stuff that's in scope, or the superfluous/verbose variable declaration preamble.

I'm a believer in restricting the scope of definitions as much as possible, and like programming languages that allows creating local bindings for creating another. For example: local val backupIntervalHours = 24 val approxBackupDurationHours = 2 val wiggleRoomHours = 2 in val ageAlertThresholdHours = backupIntervalHours + approxBackupDurationHours + wiggleRoomHours end Then it's easier to document what components a…

Mentally discarding a name still takes some amount of effort, even if local.

I often write things the way you have done it, for the simple reason that, when writing the code, maybe I feel that I might have more than one use for the constant, and I'm used to thinking algebraically.

Except, that I might make them global, at the top of a module. Why? Because they encode assumptions that might be useful to know at a glance.

And I probably wouldn't go back and remove the constants once they were named.

But I also have no problem with unnamed but commented constants like the ones in the comment you responded to.

Re: Maybe comments should explain 'what' (2017)

#149
post #36

Earlier quoted context omitted.

> where each line is extracted into its own method Never heard of "that style of programming" before, and I certainly know that Uncle Bob never adviced people to break down their programs so each line has it's own method/function. Are you perhaps mixing this with someone else?

This is from page 37 of Clean Code: > Even a switch statement with only two cases is larger than I'd like a single block or function to be. His advice that follows, to leverage polymorphism to avoid switch statements isn't bad per-se, but his reasoning, that 6 lines is too long, was a reflection of his desire to get every function as short as possible. In his own words, ( page 34 ): > [functions] should be small. The…

He has expressed admiration for lisp, and he comes from a time before IDEs. These may color his desired level of complexity.

Re: Maybe comments should explain 'what' (2017)

#150
post #97

I made a point here https://antirez.com/news/124 that comments are needed at the same time for different reasons, and different comments have differente semantical properties that can be classified in classes you very easily find again and again, even in very different code bases.

This is a great post and meshes with how I like to comment as well. I like to break the so called rules and get a bit dirty when it comes to writing code and comments. My opinion which you state, is to remove the effort from the reader in needing to figure things out a second, third, or n-th time. Here is one I wrote just to talk about iterating a loop in reverse: /* * We iterate the v6 prefixes in reverse from longe…

Except your giant comment doesn't actually explain why it used uint64. Only place mentioning uint64 is integer promotion which only happens because you used 64bit integer, thus no explanation of why.

Was it done because shifting by amount equal or greater to integer width is undefined behavior? That would still not require storing result in 64bit mask, just shifting (~0ULL) would be enough. That would be a lot more valuable to explain than how bitwise AND works.

The first one also seems slightly sketchy but without knowing rest of details it's hard to be sure. IPV6 address is 128bits, that's 2 registers worth integers. Calculating base address would take 2 bitwise instruction. Cost of copying them in most cases would be negligible compared to doing the lookup in whatever containers you are searching resulting address. If you are storing it as dynamically allocated byte arrays (which would make copying non trivial) and processing it in such a hot loop where it matters, then seems like you have much bigger problems.

For my taste it would be sufficient to say "Iterate in reverse order from most specific address to least specific. That way address can be a calculated in place by incrementally clearing lowest bits." Having 2 paragraphs of text which repeat the same idea in different words is more distracting than it helps.

Post reply on HN