I used to believe in "self-documenting code," but it takes far longer to read through code than it does to read a comment on the code, and you're far more likely to come away with an intuitive and correct understanding, and with far less effort, by reading a comment than code. When reading actual code, your understanding of how the piece of code might be incorrect, which could domino to bigger errors down the line. Also, it might be easy to overlook some critical line in the function which significantly affects its behavior.
Perhaps most importantly, most of the time you don't need to know how something works, only what it does. Unless you have a reason to doubt that the function does, in fact, do what it says it does, it's much nicer to have a few lines of comments -- written in human language -- to describe the inputs and outputs of some function, or the reason we're invoking some function here, than to have to actually go and read through the code of a function. In fact, reading through the actual code can sometimes impede understanding, because of the reasons I stated above. Now with some functions, this purpose can be entirely expressed in the function signature, but with more complicated functions, that's unlikely.
Exactly. This "code is the documentation" mentality is simply laziness or an excuse for poor engineering.
How about "the bridge is the documentation" for civil engineers? Or "the house is the documentation" who needs building plans?
Documentation also has to cover larger scale interactions, that is how objects interact with each other and how they fit into the design.
All that said, in a large software project you need to pick your battles. Maintaining the same level of documentation across the board and throughout the life of the software is very difficult. Make sure though that your core is well documented and you keep that documentation up to date. Libraries and APIs used externally also need to be well documented.
The equivalent of source code in civil engineering (and engineering of physical things in general) is the drawings/plans, not the actual bridge. In practice it turns out that drawings for physical objects are often even worse at comments than software, in part because leaving comments on CAD models is so much less convenient than in code.
Not exactly. The drawings I've worked with had lots of annotations on them (e.g. dimensions and manufacturing instructions). I agree it's not a perfect analogy but perhaps uncommented/undocumented source code lies somewhere between the physical thing and the drawings (or CAD file). My point though is that in theory every bit of information can be observed from the physical object it is a poor way of storing that information.
Perhaps most importantly, most of the time you don't need to know how something works, only what it does. Unless you have a reason to doubt that the function does, in fact, do what it says it does, it's much nicer to have a few lines of comments -- written in human language -- to describe the inputs and outputs of some function, or the reason we're invoking some function here, than to have to actually go and read through the code of a function. In fact, reading through the actual code can sometimes impede understanding, because of the reasons I stated above. Now with some functions, this purpose can be entirely expressed in the function signature, but with more complicated functions, that's unlikely.