I disagree. Function names should describe, as clearly and as precisely as possible, what they do rather than why they do it in one particular way.
I find comments helpful when the implementation of a function is surprising, i.e. it diverges from patterns one might normally expect for similar tasks. Specialized performance optimizations would be one example I can think of.
ADRs are useful, but I’m not sure they make much sense for implementation details at the level of a function.
All that said, I do agree that functions should be clear in name and content and I think comments should be rare.
A function which is only used once is code smell to me. A function with 200 lines of code and a few comments here and there which I can read from to to bottom can be much more readable than 20 10 line functions for which I have to jump back and forth.
I agree with 200 functions being bad, but breaking them up into private functions won’t help you with unit testing, unless you do the other sin of testing private functions. Sometimes you end up with large functions, but when you do it might be a good time to consider creating a new class to spread the responsibilities a bit.
In my experience function calls are mostly for breaking my flow of reading. I don’t see why you couldn’t add structure with newlines and comments.
It could be that I’ve only seen bad code and if you do it good it actually improves readability. But I think there’s more chance I’ll encounter a unicorn than good code.
What’s the alternative? Write an inline sort routine 30 times?
I’m not so sure the example is particularly good. Assuming the sort is just a one line call to a library routine, then the comment would be unnecessary. You call the API, then you sort the results and it should be obvious to any maintenance programmer why. Don’t comment obvious stuff.
If you are doing this 30 times, then put the API call and the sort in a subroutine called callApiAndSort().
The suggestion was that a comment be used when the reason for the sort was not obvious. Not that every sort be commented to explain why. So there’s no reason why you’d wrap every sort call in a custom subroutine either.
The alternative is to just call the sort function and add a comment if the reason why it’s being sorted isn’t obvious rather than making a new function so that the function name can act as the comment.
I just see “never do x, no exceptions” as overly constraining yourself when sometimes a comment might be a better option than jumping through a hoop that involves having a function named “sortRandomAPIResults” just to avoid ever using a comment. Even goto statements have cases where you get better code from just using goto than everything required to avoid it.
Better to understand the purpose of the thing you are doing and to be aware of the pitfalls using it might subject you to. Yeah, there are a ton of comments out there that are useless or even misleading, but there are helpful ones, like if a function encodes some data for some specific spec, a comment that includes information about that spec can help. Like url for documentation, or a description of the relevant fields it’s filling in. Yeah, you could get that from data structures and looking at the code, but it’s a bit more mental effort to do that, plus it assumes the code is correctly doing what the programmer intended it to do.
If some code looks very close to some standard math thing but is slightly different, is that a bug, a way that this case differs from the usual case, or an optimization? Iirc Carmack introduced some optimisations for 3d rendering doom that even he wasn’t fully aware of how they worked, just that they were able to test the output over the range of relevant inputs and determined that it always gave a solution that was good enough to be able to skip some slower method that was easier to understand.
And there’s also language barriers. Some code that looks very descriptive to you might not be so obvious to someone who isn’t a native speaker or even just has sufficient cultural differences to not pick up on a reference. I’d bet that translation tools, that don’t always do great at translating meaning rather than words, will struggle even more if that meaning is encoded in C++ as well as English.
Hard and fast rules are for beginner, but their code is going to be crap anyway.
For everyone else, comments when it makes the most sense is all you need.
I will say that following a few simple principles, when appropriate, like “Don’t Repeat Yourself”, and the “Single Responsibility Principle” tend to lead to smaller methods with clear intent that give better opportunities to name things appropriately.
If I see well laid out code with one or two comments, I’m likely to actually read the comments. Otherwise I view comments as meaningless noise.
Comments shouldn’t explain what you’re doing, but why you’re doing it
That’s what the function name is for
If you can’t succinctly describe a function by its name, it’s too big and should be split up
If it still needs explaining, the only acceptable comment is an ADR reference to the doc with the actual detail
I disagree. Function names should describe, as clearly and as precisely as possible, what they do rather than why they do it in one particular way.
I find comments helpful when the implementation of a function is surprising, i.e. it diverges from patterns one might normally expect for similar tasks. Specialized performance optimizations would be one example I can think of.
ADRs are useful, but I’m not sure they make much sense for implementation details at the level of a function.
All that said, I do agree that functions should be clear in name and content and I think comments should be rare.
A function name says what it does, not why. Or do you name your functions “thisLooksABitWeirdButItsBecauseThePrintFunctionDoesntSupportKanji”? 😋
A function which is only used once is code smell to me. A function with 200 lines of code and a few comments here and there which I can read from to to bottom can be much more readable than 20 10 line functions for which I have to jump back and forth.
A 200 line function tells me the code is very likely to be inadequately unit tested and/or is going to be fragile when it’s changed in the future.
Functions aren’t only for code reuse, they are for structuring your code.
I agree with 200 functions being bad, but breaking them up into private functions won’t help you with unit testing, unless you do the other sin of testing private functions. Sometimes you end up with large functions, but when you do it might be a good time to consider creating a new class to spread the responsibilities a bit.
In my experience function calls are mostly for breaking my flow of reading. I don’t see why you couldn’t add structure with newlines and comments.
It could be that I’ve only seen bad code and if you do it good it actually improves readability. But I think there’s more chance I’ll encounter a unicorn than good code.
brother back in the day you got 8 characters for a function name. that’s why c functions have awful names.
What about a comment like “The API returns stuff basically in random order, you gotta sort them first”?
Put that code in a method called something like sortRandomApiResults().
So now you need 30 different functions that sort things, named for each reason you need to sort things?
What’s the alternative? Write an inline sort routine 30 times?
I’m not so sure the example is particularly good. Assuming the sort is just a one line call to a library routine, then the comment would be unnecessary. You call the API, then you sort the results and it should be obvious to any maintenance programmer why. Don’t comment obvious stuff.
If you are doing this 30 times, then put the API call and the sort in a subroutine called callApiAndSort().
The suggestion was that a comment be used when the reason for the sort was not obvious. Not that every sort be commented to explain why. So there’s no reason why you’d wrap every sort call in a custom subroutine either.
The alternative is to just call the sort function and add a comment if the reason why it’s being sorted isn’t obvious rather than making a new function so that the function name can act as the comment.
I just see “never do x, no exceptions” as overly constraining yourself when sometimes a comment might be a better option than jumping through a hoop that involves having a function named “sortRandomAPIResults” just to avoid ever using a comment. Even goto statements have cases where you get better code from just using goto than everything required to avoid it.
Better to understand the purpose of the thing you are doing and to be aware of the pitfalls using it might subject you to. Yeah, there are a ton of comments out there that are useless or even misleading, but there are helpful ones, like if a function encodes some data for some specific spec, a comment that includes information about that spec can help. Like url for documentation, or a description of the relevant fields it’s filling in. Yeah, you could get that from data structures and looking at the code, but it’s a bit more mental effort to do that, plus it assumes the code is correctly doing what the programmer intended it to do.
If some code looks very close to some standard math thing but is slightly different, is that a bug, a way that this case differs from the usual case, or an optimization? Iirc Carmack introduced some optimisations for 3d rendering doom that even he wasn’t fully aware of how they worked, just that they were able to test the output over the range of relevant inputs and determined that it always gave a solution that was good enough to be able to skip some slower method that was easier to understand.
And there’s also language barriers. Some code that looks very descriptive to you might not be so obvious to someone who isn’t a native speaker or even just has sufficient cultural differences to not pick up on a reference. I’d bet that translation tools, that don’t always do great at translating meaning rather than words, will struggle even more if that meaning is encoded in C++ as well as English.
Hard and fast rules are for beginner, but their code is going to be crap anyway.
For everyone else, comments when it makes the most sense is all you need.
I will say that following a few simple principles, when appropriate, like “Don’t Repeat Yourself”, and the “Single Responsibility Principle” tend to lead to smaller methods with clear intent that give better opportunities to name things appropriately.
If I see well laid out code with one or two comments, I’m likely to actually read the comments. Otherwise I view comments as meaningless noise.
Sets are unordered, no need for this specific comment
What if the API returns a randomly ordered list?
That should be evident from the code and probably a unit test if it matters that the data is sorted in some way
No comment needed
Lemme guess, you read that ‘clean code’ book and spout its BS non-stop.
I was kinda done responding to this thread, but it has to be made clear that Bob Martin is a wanker
And avoiding writing shit code doesn’t have to have anything to do with that bigoted twat