There are many great developers, many bad developers and any number in between. But subjective judgement is often temporal: a bad developer one day can be a great one the next. In any human endeavour, circumstance plays a large part in shaping perception and opinion.
Regardless of the skill and competency, there has never been a developer who writes self-documenting code.
Self documenting code is a myth
Such an innocuous statement splits the developer community. There are those who believe that the code they write is fully self-documenting: names of functions are chosen with the utmost consideration, variable names have been considered with such care that the purpose of the variable is apparent and the concept that “the code is the documentation” is prescribed, and often given authority by attributing that statement to some greater authority within the developer community.
I was once tasked with writing a “coding standards” document for a large enterprise. My first line was, “Self-documenting code is a myth”. If I’d actually written, “I’ve slept with your mum”, my document would probably have received a slightly less vitriolic reception. Inside this particular cabal I was supporting code in which there was a class named ‘TemplateProductEffectivityGroup’. With a background knowledge of the business this term was understood by the developers but, developers being human, it was quickly abbreviated to the acronym ‘TPEG’. And this was before referring to the attributes of this class, which had now acquired almost Germanic-sounding compounds such as TemplateProductEffectivityGroup::StartDate or TPEGStartDate, if it’s easier for you to remember.
A car without a motor
At the other extreme are developers who produce documentation in such volume as to obscure the code and who rely upon the documentation to handle poorly implemented naming conventions. The accusation that can be levelled at extreme documentation is that it is notoriously difficult to keep it in synchronisation with the code and makes finding the actual code problematic. I supported a codebase where, within the fantastically commented code, we found parts of the code that had absolutely no effect. It was a bit like a car without a motor and probably not the author’s intent.
As in most things, the true path lies somewhere in between. Given the opportunity most people will take a shortcut, whether it’s by abbreviating overlong names or by not updating documentation. What documentation in code does is to allow the author to attempt to convey the intent of the code, as well as attempting to implement the action via code. The same can also be said about well-chosen class and variable names.
No natural language, e.g. English or German, can provide a lexicon and grammar to fully prevent misunderstanding. We use supplemental media, such as hand and facial gestures, as aids to support linguistic communication; the internet is littered with flame wars that arose from relying solely upon written verse. In verbal communication we often rely upon near-repetition to convey the full sense of our meaning.
Neither absolutely comprehensive documentation nor self-documenting code can be unambiguous. Just as a carpenter does not use a chisel alone to perform the trade, so a developer cannot rely upon one tool or maxim to perform theirs.