Beyond "Clean Code": Why Your Comments Matter

(blog.moertel.com)

23 points | by chmaynard 2 days ago ago

10 comments

  • johnmwilkinson a day ago ago

    I completely agree. I wrote a book on the subject of how to write clear code (Bob Martin was off by one letter!) and comments are a key element of that.

    https://elementsofcode.io/chapters/documentation/

    We’re in good company: Jon Ousterhaut had a conversation with Uncle Bob where he brings up the exact passage you quote as a point of disagreement.

  • 4xel a day ago ago

    While I agree with the conclusion, I don't agree with all the examples given.

    > Invariant: From this point on the array’s length must be 3N + 1 for some integer N.

    Invariant can be checked by code, and they definitely should if your language allows constraints or asserts (checked at comptime or ran in test and debug mode)

    > We use simple brute force here because instances are guaranteed to be small (see guard above).

    The guard above probably conveys the information already.

    > Limit each request to one day’s data; otherwise, we won’t get 1-minute resolution.

    This could be a benchmark, though I wouldn't be unhappy to read this as a comment, and I wouldn't care if there was no benchmark.

    A couple others could be in a separate technical doc rather than in comment. I'm on the fence about it, a bit more on your side, but there are ways and places to express intent outside of the source code that the "no comments" crowd may argue for.

    As for the python example, it's a great illustration of your point, there are many comments, but it's hard to remove any. Still:

    # Weights must be non-negative integers. and # The distribution must have a positive total weight.

    Can be discarded without losing anything: the parameter validation they comment is already transparent, and even includes natural language in the error message, describing what happens why.

    Some other comments describe the what rather than the why, but the code it refers to is dense enough that it's warranted.

    • tmoertel 21 hours ago ago

      This is great feedback. Thanks! Let me provide some additional context. Maybe it will change your mind about some of these examples? But just to be clear, I think all of your takes are reasonable.

      > While I agree with the conclusion, I don't agree with all the examples given.

      > > Invariant: From this point on the array’s length must be 3N + 1 for some integer N.

      > Invariant can be checked by code, and they definitely should if your language allows constraints or asserts (checked at comptime or ran in test and debug mode)

      Yeah, it’s hard to tell without the context, but the code’s logic is actually checking (and branching on) this invariant repeatedly. The comment is here to remind the reader of this invariant that was established earlier.

      > > We use simple brute force here because instances are guaranteed to be small (see guard above).

      > The guard above probably conveys the information already.

      The guard only conveys a size limit. It does not convey that the limit is considered small for the brute-force algorithm. Rather than have the reader wonder whether the upper end of the limit is too large for brute force, we answer this question directly at the place it would naturally occur to a reader.

      > > Limit each request to one day’s data; otherwise, we won’t get 1-minute resolution.

      > This could be a benchmark, though I wouldn't be unhappy to read this as a comment, and I wouldn't care if there was no benchmark.

      Without this comment, it would be a mystery why we are adjusting the start of a range. Here’s the actual code. Please let me know whether you think this comment ought to be removed: https://github.com/tmoertel/tempest-personal-weather/blob/ma...

      > A couple others could be in a separate technical doc rather than in comment. I'm on the fence about it, a bit more on your side, but there are ways and places to express intent outside of the source code that the "no comments" crowd may argue for.

      > As for the python example, it's a great illustration of your point, there are many comments, but it's hard to remove any. Still:

      Thanks!

      > # Weights must be non-negative integers. and # The distribution must have a positive total weight.

      > Can be discarded without losing anything: the parameter validation they comment is already transparent, and even includes natural language in the error message, describing what happens why.

      That’s a reasonable conclusion. I prefer to keep those comments, though, as a matter of emphasis. The logic will rely on these mathematical properties, so I didn’t want them to be glossed over as mere input validation.

      > Some other comments describe the what rather than the why, but the code it refers to is dense enough that it's warranted.

      Agreed :-)

      Thanks again for reading my article carefully and for sharing your insightful feedback!

  • magicalhippo a day ago ago

    I reached the same conclusion.

    Yes, absolutely let the code be self-documenting by structuring it well, using well-named functions and variables and so on. This will make it clear what you're trying to do.

    So yes, you shouldn't write "check if greater than two" in a comment, that should be obvious from the code itself.

    But sometimes the why is very important, and it is not readily obvious from the what. Ideally try to modify the code so it becomes clear.

    Don't just check against two, check against a named constant that provides information through the name.

    However what can be more difficult to express cleanly is for example why the check is being done here and not somewhere else, in the cases where that matters.

    In those cases, help the reader by adding some clarifying comments as to why this is being done.

  • wduquette 21 hours ago ago

    I'm mostly a solo programmer, and I often have to go back and look at code I wrote five, ten, twenty years ago. And every time I do, I give thanks that I used comments to document my intent. My memory's good, but it's not that good.

  • mrozbarry a day ago ago

    I think Bob Martin would generally agree. I think his gripe was using comments to make your code more readable, and that's a problem. Variable and function naming should make the code logic clear and readable. When it comes to feature requirements/explanation, that's a different thing, and a hard problem. Documenting features in code means it's only available to coders. Duplicating feature documentation from some external source to code means it risks becoming out-dated.

    Syncing tickets, bug fixes, code, and feature details is a hard problem. I'd generally prefer doc-block style comments that link to feature/product documentation, which is good for humans, and probably LLMs, too. Wherever you put it, keep it consistent and searchable.

    • wduquette 21 hours ago ago

      Re: Mr. Martin's agreement, whether he agrees or not is not nearly as important as the impression his book gives and whether your "Clean Code"-reading co-workers agree. I know people who genuinely try to get rid of all comments as "Clean Code" suggests, and I'm glad I don't need to maintain their code.

    • tmoertel a day ago ago

      Thanks for your feedback. I am not sure Mr. Martin agrees with me, however.

      To be frank, I don’t know how to interpret Martin’s advice. If his concern was, as you suggest, that comments can be abused as a crutch to prop up confusing logic, why isn’t that what he wrote? You were able to write words to that effect. So was I. Presumably, Martin would have been able to write similar words—if that were what he wanted to say. After all, he has written several published books.

      But in his book Clean Code he opens the chapter on comments with a far more radical thesis:

      > The proper use of comments is to compensate for our failure to express ourselves in code. Note that I use the word failure. I meant it. Comments are always failures. We must have them because we cannot always figure out how to express ourselves without them, but their use is not a cause for celebration... Every time you write a comment, you should grimace and feel the failure of your ability of expression.

      Later in the same chapter, he undermines his thesis by presenting some examples of “good comments.” If we take his word that these comments are good, but also take his word that “comments are always failures,” we are led to conclude that good comments are failures, which is absurd.

      After he wrote the section on “good comments,” how could he not realize that it refuted his thesis? Why, then, didn’t he revise his thesis accordingly? He certainly had the opportunity and the writing ability. The only explanation I find plausible is that he didn’t want to revise his thesis. He somehow thought it was helpful to instruct his readers that “Every time you write a comment, you should grimace and feel the failure of your ability of expression.”

      So I’m not sure what he’s trying to say. It’s hard to believe that his opening thesis is anything other than what he wanted it to be. It’s a mystery, however, why.

  • blinkbat 2 days ago ago

    I disagree that it's the codebase's job to communicate product's intent

    • tmoertel 2 days ago ago

      Thanks for your feedback. (I am the author of that article.) I was trying to argue that it’s the code’s job to communicate its authors’ intent for the code itself. To help me clarify my writing, can you tell me what I wrote that led you believe I was talking about intent at the product level and not the code level? Thanks!