Luckily, both camps on this discussion are represented here, and pro and con arguments for both were mentioned.
I believe both camps have overlapping arguments, and actually agree on most of them, just the way how to achieve them is a bit different.
Overlapping arguments
- Code should be readable.
- Comments shouldn't say the exact same thing as the code does, but give further insight where necessary.
- All variable/function names should be given good thought so they give a good representation of what they are/do.
- Duplicate code should be prevented.
Now, the main difference is how much weight is put on some of those arguments.
Self-describing code
- Comments can get obsolete, so minimize using them, as wrong comments are worse than no comments.
- Comments are a duplication of the code. Everything which can be written in code, should be written in code.
More comments
Comments are more readable than code. Plain english is better at describing something.
Plain code often causes ambiguity which has to be commented anyhow. Trying to describe this in code, results in too long names. Furthermore, you are constantly confronted with this 'extra' information which you only need the first time you come across it.
I believe both camps have very valid arguments, but you shouldn't frantically follow one camp, just because it solves one issue.
To demonstrate, in the book Clean Code, code is broken down into numerous smaller methods which are only called once. Methods are created for the sole reason to document the code (and easier TDD). This results in Function Hell. The code is less readable than it was originally, and while refactoring, no thought was given to encapsulate reusable code.
On the other hand, you often see API's where every function is commented, just because 'comments are good'. The things which should have been commented still aren't.