The problem with commenting code is that code is constantly refactored to deal with new invariants and edge-cases. What starts out as a great way to summarize the purpose and mechanics of a given function or statement becomes immediately stale once the function or statement is changed. In the best case, the comments are revised along with the code they describe.
However, everyone makes mistakes, as you have pointed out, and once a comment is forgotten during refactoring, that comment has become a liability to the future maintenance or use of the code it describes. Given that comments are, by definition, not executable lines of code, commenting errors do not show up in code execution. Since most bugs only become apparent because of incorrect execution, commenting bugs are difficult to spot. This is a problem when developers read the comment instead of the code to discover the purpose and mechanics of the commented function or statement, and can lead to further errors in client code of the function or statement when the called code doesn't conform to the specifications expressed in the comment.
Now the developer who has to fix the code has two things to debug; the code as it is written and the code as it is described in the comment. Which has authority? How do you prove the correctness of a comment?
You can prove the correctness of code, because it can be executed. You can test it using the scientific method, trace its execution paths at runtime and by reading the calling code. You cannot do this with comments.
Additionally, every line of source code is a liability to the maintenance of the code. Each line out source adds computational and mental complexity to the program they describe.
For these reasons, good, verbose variable and function names to describe the what, and corresponding tests to describe the how and why are superior ways to describe code over verbose comments.
The point of a summary though is to offer the promise of an interface. The code should implement the summary, not the other way around.
Code comments though are different. They are there to annotate code. They are incredibly useful in collaborative environments but only if they are used to organize, discuss, and debate the code, not describe it.
However, everyone makes mistakes, as you have pointed out, and once a comment is forgotten during refactoring, that comment has become a liability to the future maintenance or use of the code it describes. Given that comments are, by definition, not executable lines of code, commenting errors do not show up in code execution. Since most bugs only become apparent because of incorrect execution, commenting bugs are difficult to spot. This is a problem when developers read the comment instead of the code to discover the purpose and mechanics of the commented function or statement, and can lead to further errors in client code of the function or statement when the called code doesn't conform to the specifications expressed in the comment.
Now the developer who has to fix the code has two things to debug; the code as it is written and the code as it is described in the comment. Which has authority? How do you prove the correctness of a comment?
You can prove the correctness of code, because it can be executed. You can test it using the scientific method, trace its execution paths at runtime and by reading the calling code. You cannot do this with comments.
Additionally, every line of source code is a liability to the maintenance of the code. Each line out source adds computational and mental complexity to the program they describe.
For these reasons, good, verbose variable and function names to describe the what, and corresponding tests to describe the how and why are superior ways to describe code over verbose comments.
However