I saw one too many posts about how responsible programmers document their code. I put out the short form of my position:
As with all short takes, I elided nuance to keep the word count down. Below’s a more thorough treatment of how I see documentation & when to write it.
Straw Arguments
“Irresponsible”. It is the responsibility of all programmers to communicate effectively with their colleagues (and their future self). Even if the business doesn’t ask you to communicate, or actively discourages you from taking the time to communicate, programmers have a duty of care to communicate. I’m not saying “don’t communicate”. I’m saying think about the tradeoffs when you consider what & how to communicate.
“No documentation”. I didn’t say “no documentation”. People reasonably commented:
I don’t have a problem with that level of documentation.
“Self-documenting code”. Not what I’m advocating. Near as I can tell, “self-documenting code” was invented as yet another excuse for programmers not to have to talk to other people. Yes, communicating through code is one of the media we should get good at using, but that’s different than whistling past “self-documenting”.
Cycle
I’ll admit to being triggered by the calls for more documentation. It’s part of the neo-waterfall movement rising recently.
Just write the specification first, then development will go more smoothly.
Design up front, then development will go more smoothly.
Have product people pick the features & hand them to programmers, then development will go more smoothly.
Don’t waste programmers’ time with tests. Have a QA department test, then development will go more smoothly.
(One wonders if “development goes more smoothly” is just the wrong goal, but that’s a topic for another day.)
I’ve been through this documentation story before. I can predict how it ends. By the time you read the documentation it’s out of sync with the code so you end up reading the code anyway. But then you feel bad, so you write more documentation & force yourself to update documentation whenever the code changes. But that takes time away from development & the pressure is on, so you stop writing/updating. So the next time you read the docs they don’t help. Damned if you do, damned if you don’t.
The more documentation the greater the burden, the greater the burden the less useful the documentation.
As I said up front, I’m not anti-documentation, I’m just anti-authority-misaligned-with-responsibility calls for more documentation.
Tradeoff
Just as every line of code you write should be justified in some way, every document you write should be justified. Here are the factors that create the sweet spot for a document:
Large audience. Erich & I happily wrote Javadoc for JUnit because we had hundreds of thousands of users. If we were writing for 3 colleagues, then we could just explain stuff in person.
Stability. If the information conveyed doesn’t change much, then documentation costs less to write/update. After the first couple of years, the JUnit API stabilized, so documenting was also stable.
Low cost of delay. If you could be writing another user experiment potentially unlocking 50% growth & instead you stop to write docs, then that’s an exorbitantly expensive document.
Alternatives
I started by saying that communication is a programming imperative. What else is a programmer to do to communicate besides writing documents?
Simplify. As someone who has spent thousands of hours writing literate programs, I appreciate the moment when I have to choose between explaining something unnecessarily complicated & removing the unnecessary complication. To paraphrase the quote about pilots, the superior programmer exercises superior design skills to avoid having to exercise superior communication skills.
Socialize. Pairing. Whiteboarding. Story-telling over lunch. We humans have used social methods for millennia to communicate our most sacred concepts.
Test. Passing tests are guaranteed to be in sync with the code. If you focus on tests as a communication medium as well as a double-check on system health, you can make them speak.
Code. Likewise, focusing on code as a communication medium yields, surprise, surprise, better communication. (I’ve written 2 books on the subject.)
In the end, write the docs you want to write. If no one reads them, or if readers find they are out of date, then consider not writing them next time. But don’t let anyone shame you into wasting time. The question is not, “Do you have documentation?” but rather, “Do you communicate clearly?”
I find it ironic that calls to increase documentation come just at the moment that LLMs are getting good at explaining code. At Mechanical Orchard we’ve developed some amazing internal tools to answer our questions about legacy mainframe code. These tools are only going to improve. The one part of software development that LLMs are clearly better at than humans is one task reactionaries have latched onto.
Once I was in a situation where I was the responsible architect and we were discussing a series of refactoring that would lead to a better design.
One of the arguments against it was' then we need to adapt all the documentation we wrote'.
Which was one of my better moments, because I then deleted all extracts of source code in the documentation and instead of describing the implementation, we wrote down the principles that guided the implementation and the decisions we made.
The truth is in the code and in the test cases :)
Just saw the "self-descripting code" phrase: Isn't that rather more an idea than a reality in software industry? I just finished one of those self descriptive projects. A doc already exists: a requirement analysis doc, the problem domain analysis resulting into nice domain model, covered by tests, some 80%. To work this way is a pleasure for me. Unfortunatelly, my usual daily software engineer work is to deal with a mess. A mess improved by my "clever solution" still remains a mess that is hard to describe.