Comments are great when they are well maintained. But for every codebase that isn't basically some open source software where the eyeballs-reading to comment-maintaining ratio is really high and people spend the time, everyone eventually forgets and/or is too lazy to maintain them. It can be almost as much work updating the comments as adjusting the code a lot of the time. So the ground truth reality is that comments are usually "lies waiting to happen". Eventually, the comments and the code won't be in sync, and this can be potentially worse than having either bare, uncommented code, or better, having actual automated tests that show intent. The tests mostly can't lie, otherwise you wouldn't have merged them presumably. If you show me a bunch of decent tests laying out how the code is intended to be used, that is what I want to see. Because it is explanatory AND it is nearly guaranteed to be truthful.
I'll take the out of date comments. They provide a red flag that either the original author was confused, or the behavior changed over time. At least then you can do code archeology to piece together descriptions of what the original intent was, and how it changed using the commit history and figure out where things went off the rails, and thus determine how to actually fix it rather than patch over it even worse.
The problem with unit test as documentation is that over time they end up reflecting the same misconceptions that the code has. Someone does a refactor, misunderstands how the original code works, and "fixes" the unit tests to pass. Now you have tests that lie just like comments can lie.
Neither comments nor lacking unit tests are going to fix that, that's a strawman argument. What I'm saying is if someone doesn't know 100% what their doing, which can be relatively often, then I would hands-down take a bunch of unit tests over some misguided comments because at least the unit tests have to /pass/, so there is some grounding in reality. A comment has absolutely no such requirement and therefore can stray in any direction forever. Also, if you refactor a name of a variable or inputnor function, you will be required to update the tests, so they are dar safer from becoming stale due to refactoring compared to an opaque string from the IDE's point of view.
I never found that to be a problem in practice. Yes, comments do get slightly out of sync, and not always corrected. But typically enough comments are correct that you can make sense of the whole thing, and can even fix the comments then.
By contrast, I have really never seen truly self documenting code. The comments may be up to date by virtue of not existing, but the end result is just more confusing. YMMV
Same, my coworker used this argument when I tried to get them to write more comments. The number of hours I've wasted due to there being no comments at all is way, way, way more than the very small number I've wasted due to a no-longer-accurate comment. And I usually find that people who write self-documenting code choose variable/function names that might make sense to them at the time, but are vague and confusing to me when I need to read the code.
Same here as well, I hear this argument a lot, but have yet to see a comment I didn't appreciate. And if there's something wrong with the comment, fix it! Self documenting code is a joke.
Code that breaks is much more likely and damaging than comments that are out of date. In my life I've never had a case where the bad outweighed the good for comments.
Also, if you're doing regular code reviews, wouldn't that include making sure the comments are up-to-date?
As for the argument that it wastes time to update comments, I've never seen a codebase where the comments were so voluminous that it would be a significant burden to update them. Devs avoid updating comments because there is usually no penalty for doing so (boss doesn't call them on it, and the code still runs), and they think they've saved a few minutes when in fact they're just kicking the can down the road for the next dev who has to decipher the incorrect (or missing) comment.
Code breaks because people read the comment and assume it speaks truth when in fact it's full of lies. And as soon as you don't trust comments you have to start reading the code. And if you're at that point now..... Why have the comment?
Comments don't replace reading code, they prime your brain for the code you're about to read. There is often context and reason behind the code that is not in the code itself.
If you ever trust comments over code you really need to adjust your approach. Comments are there to help guide you towards the intent of code, not to let you ignore code. Same reason why if a function has a bug, you don't ignore that bug just because the function's doc says otherwise.