Think of it more like two lines of bearing. You are far more likely to get an accurate position from two lines of bearing. If you need to understand what past self was thinking, a comment is written in a different mindset than the code. Two different lines of reasoning.
Also, I rarely think about writing code for someone else. I write for my future self. And I really want my future self to like my past self. So I strive for clean code and write detailed comments, complete with references.
I mean in theory yes, but in practice I've usually found comments in such situations to either be missing, outdated or misleading.
>If you need to understand what past self was thinking, a comment is written in a different mindset than the code.
I don't think I agree with this at all, why would the mindset be different when they were both written at the same time?
Like I said, writing good comments requires just as much if not maybe more self awareness of what you're likely to forget in the future as writing clear code. I think if you're at that level where you can successfully muster that, you should spend your time just making your code clearer.
In reality I think it's even difficult to muster that requisite introspection skill in the moment and it's usually best left until after you solve the problem (let's say, the next day) to go over the code and check how clear it really is.
Your experience is different than mine: I write software which interacts with cloud (Amazon AWS, Google Compute Platform, VMware vSphere), and a well-placed comment describing the quirks of whatever platform I'm working with helps immeasurably, e.g.
> VMware NSX will throttle us with an HTTP Status 429 "Too Many Requests" if > 100 API calls/second. In that case, we back off and retry rather than fail.
Yes, you're a seasoned HTTP developer. The comment isn't meant for someone like you. It's meant for the other developers on a shared codebase who may not know much beyond the standard HTTP status codes (200, 400, 403, 404, 503).
> taking up more lines to describe the method than execute it
It's a one-line comment. the Ruby code with the exponential backoff, eight lines. It does not take up more lines than the method.
My approach is that conventional knowledge doesn't need to be documented in comments. Attempts at guessing how much conventional knowledge someone is lacking are futile. Those comments are similar to:
int a = 4 // set a equal to four
If someone doesn't know what 429 is, they should get confused, do their own research, and learn. Comments should not be turned into educational material about open standards, they should be about your business. There are much better places to learn about standards.The code comment in the GP is pithy, explanatory, and reads in plain English. Yours is ripe for misunderstanding.
301; 302; 401; 429; 504; I shouldn’t need comments to tell me what they are, nor should it be expected that anyone touching the code knows them off the top of their head.
I don't mean to imply that your code is poorly written as I clearly can't see it and maybe it's a lot more complex than I am imagining it, but I don't really understand how your code was written such that it became unclear enough what code handling a 429 was doing such that you felt you needed a comment to explain it, but I can envision a codebase which handled rate limiting where comments weren't needed to explain the reasoning behind it.
I think the best way to think about it is this: What information is this comment conveying?
- "HTTP Status 429" means "Too Many Requests" - You can put this information in a comment every time you refer to 429, or you can simply use an enum.
- "429 Too Many Requests" means "a rate limit has been hit" - You can put this information in a comment every time you refer to the enum, or maybe it's best placed on a website like MDN[0] where it can be surrounded with far more detail and where the information has a much smaller chance of becoming outdated.
- The rate limit is 100 API calls per second - You can put this information in a comment every time you talk to this particular API, or it's best placed in a document which describes the API itself such that if you ever need to update it, you can update it once. Maybe you can demand that the vendor of the API provides and maintains this document as part of whatever contract you have with them. If necessary, the module of your code which deals with interacting with this API may benefit from a reference to this document.
- That the code should back off and re-try instead of failing - Okay, now we're getting to the core of something important. And I think the reality is more complex than the comment even lets on. Does the code re-try indefinitely? Does it have an option to disable retries in some contexts? I'd assume most likely a no for the first question and possibly a yes for the second. In that case, the names of variables within the code the name of the function, and the names of the parameters of the function should probably be enough to convey this meaning entirely.
That being said, I think that as far as comments go, there is still a benefit of having short descriptive comments for WHAT a function does for every function in a codebase. I've found that they're much more useful (as proper editor tooling can show you them whenever you make use of a function) and by being short and ONLY describing the _what_ and not the _why_ or _how_, the comments have a better survival rate and encourage people to avoid trying to make individual functions too complex.
In this case, your function may benefit from a comment such as:
// Request foo from bar, optionally backing off and re-trying <retries> times
The function signature itself might look something like:
foo(..., retries: Optional[int]) -> ...
Or alternatively you could do something similar with an explicit timeout instead.
The only missing piece I can think of is that if you have some form of back-off you probably need some initial delay before retrying, in this case this should probably be made a constant and this constant (without making any explicit references to its value or whatever value it is based on) may benefit from some reference to the method by which it was chosen. If you do intend to make it depend on the actual rate limit (e.g. 100 requests per second) then that should itself be a constant. But I think generally code like this should be avoided due to its fragility.
In any case, it is again difficult to give too specific of a recommendation given that I haven't seen the code but I don't think the comment you gave is a particularly good example of something I would personally ever recommend or want to see in the middle of a block of code.
[0]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429
Agreed, they "_should_" write the reason why, but many committers unfortunately write the "what" rather than the "why".
I like comments in code, and they're the first thing I read when, say, browsing the kernel or the Golang standard libraries/packages. And I appreciate that you don't find them as useful--more power to you!
Regarding why I don't think that clear code should have comments, it's very simple, comments are not type checked or syntax checked or even tested (unless, I guess, you hire someone to read them). It's very hard to ensure that over time comments don't deteriorate and become unhelpful. This is a much larger maintenance burden than the maintenance of clear code itself.
I think a lot of the issue boils down to people assuming that because all the code they've ever read was unclear, that code itself is inherently unclear.
Imo, first, they are two different skills. And second, sometimes it is easy to write down what I am trying to achieve, but hard to achieve it with clear code. And other times it is vice versa - easy to write the code and hard to put it into words.
This is true, but if you just get these same people to write more comments, they will also think their comments are clear when they're, in fact, not. I think anyone who is capable of writing clear comments is also equally capable of writing clear code.
If I was to suggest investing time in learning some skill, I would suggest learning how to make your code actually clear by getting the right people (with relevant domain expertise, but without experience with the code) to critique it for clarity rather than learning how to make your comments actually clear.
Why questions are best answered in architecture documentation, the code itself should be self explanatory (given the architecture documentation) for the most part with specific why comments carefully placed in places where it doesn't make sense to use the architecture documentation.
I've read code from various codebases from various companies, large and small. I very rarely see a comment which is genuinely both well placed and useful. From the bits of the linux kernel that I have worked on, I have generally seen pretty good why comments, although I think a lot of them could be shifted into architecture documentation.
All in all, when reading code, my default stance is to ignore comments unless I get lost reading the code, then I attempt to read the comments. It has been incredibly rare that I've found unclear code to have clear comments.