Why programmers don’t write documentation
kislayverma.com
kislayverma.com
I have moved to a FAANG and their documentation is downright fucking awful. _everyone_ just writes code, with lots of "clever" bits, and doesn't bother to fucking comment.
Not only that because people don't even _comment_ their code, the wiki is a total shit show. Want to know how to use a Queue? tribal knowledge. want to know which DB is best for x? tribal knowledge. Want to know how to create a new endpoint? tribal knowledge.
Worse still, we had a class during induction where some ponytailed "10x" said "If you are messaging me asking questions, I can't help other people" I didn't have the bollocks at the time to ask why his documentation sucked arse. There seemed to be a weird pride in the fact that people needed to message him to figure his shit code.
The moral of the story is this:
fuck off with your clever code, spend that effortyou put into learning new languages, or trying a new techniques and put it into developing your writing skills. It takes empathy, organisation and skill. It'll make you a better programmer and a better person.
The type of documentation you described - code comments and wiki entries - they don't need practice. They only need care.
If you know how to write a function that takes Foo and transforms it into Bar under conditions X and Y, you also know how to just append this above it:
//! Transform Foo into Bar
//!
//! Foo must be an X-ing Quux adhering to Y.
//! Foo is not modified.
//! Returns a Bar that is Z.
No knowledge or skill needed. And will make everyone's day nicer.I'm not sure what to do about lack of care in a team/company, other than trying to promote it by example.
The parts that are difficult to see and difficult to understand are the one that need documentation. They are the ones that happen to be difficult to explain.
In C++, at the very least the preconditions X and Y, as well as the invariant Z, will usually not be apparent from the function signature. Whether the argument is modified? That's usually clear from the use of const... except when it isn't, e.g. because the function is a universal-reference template, or some C compat thing that must use bare pointers because reasons.
In JavaScript, you won't even know Foo, Bar and Quux, unless someone puts it in the function name.
The primary benefit of such comments is to encode enough information that isn't obvious from the signature, that you don't need to read the actual implementation. It's particularly useful if you're using an editor or IDE that can pull signature comments and show them during auto-completion - it saves you from constantly jumping into other places in the codebase, just to verify if you're picking the correct function for the task.
E.g.
char* strncpy(char *dst, const char *src, size_t n)
and size_t strlcpy(char *dst, const char *src, size_t size)
both copy a string from src to dst with a limit on the number of bytes copied. Good comments for would not simply explain what they do and what the arguments/returns represent, but under what circumstances to prefer each variant.Going with the "6 W's":
"How" (does this code work) and "What" (does this code do) can mostly be explained by the code itself, although comments should be used to clarify anything non-obvious, for instance if you're depending on a side effect or something.
"Where" (should you use this code) and "why" (should you use this code) need to be covered by comments. It is extremely hard to figure those out from the code alone.
"Who" (wrote it) and "when" (was it written) should be in the version control system metadata. Putting those in comments is a good way to ensure the comments are out-of-date/wrong in any long-lived codebase.
https://linux.die.net/man/3/strlcpy
https://linux.die.net/man/3/strncpy
Note how most of the text there is focused on the "How" and "What", because both functions have a bunch of requirements for their arguments that are not expressed in their respective signatures.
Some languages have better tools for expressing these requirements in code. But when they can't be expressed in a way that can be enforced by the compiler, IMO they absolutely need to be mentioned in an interface-level comment (i.e. above function signature), to give users a fighting chance of avoiding bugs.
Also worth noting that the particular constraints around strncpy() and strlcpy() will not be obvious in the implementation either - the programmer trying to make use of these functions would have to study the implementation to notice potential issues. A well-placed comment can save them an expensive context switch here.
Yes, they do.
> They only need care.
They need that, too, but “care” is what gets you to apply what you know of how to do it rather than neglecting it, but practice (and interactive practice with feedback, specifically) is how you develop the skill to make useful comments, and ideally only useful comments.
> If you know how to write a function that takes Foo and transforms it into Bar under conditions X and Y, you also know how to just append this above it:
Well, mechanically probably you know how to. But absent relevant practice you might not know that (assuming, for the sake of argument, that this is correct in context — and in many cases, IMV, it wouldn’t be as much of that seems to reiterate information that is contained in type signatures and thus violate the principle of single source of truth if placed in comments) you should prepend comments with that content, rather than none or some other content foe the function.
Stupidly Simple Code is the best code, but it is also possibly the hardest to write from a programmer perspective.
I’ve always preferred reading, and the trend to everything being on YouTube has driven me nuts, but I’m a convert to this method for a few reasons.
First, it’s fast. I can sit down and make a deep dive video in 30 minutes and not have to sit around writing and polishing documentation for hours. When the code inevitably changes, I can throw away the old video and spend another thirty minutes making a new one.
Second, I can demonstrate what the code does while offering instruction around it. If I likened it to anything, it’s like having a series of lectures to your code base rather than a textbook.
And lastly, it’s proven GREAT for on boarding a new engineer in the more complex aspects of the project. Because they can go and view thousands of PRs, 90% of which have video demonstrations or explanations, they can do a lot of self directed learning and not require nearly as much over the shoulder time with other engineers. When your team is spread across 12 hours of time zones, this is very useful.
This method isn’t a panacea, and we still keep written documentation when we need to provide a concise set of “how to’s” to other teams. But for the dev team, it’s been great.
For example, creating a virtual environment for a python project instead of installing it globally. This is a crucial step for things to work well, but it's so common it might be left unstated.
So, our company creates videos, no one except new people watches them and everybody complains about lack of documentation.
I've only done it once so far, but I created a short video with Loom to demonstrate how a bug could be caused in the PR that fixed it.
Searchability is probably what would suffer from this approach, and the fact that text is much easier to edit (both for succinctness and correctness).
I prefer it if people just write it down so I can ctrl-f or find it in a web search and get what I need instead of sitting through your videos.
For general "welcome to Team X!" onboarding or training though I agree that videos have benefits. But for day to day knowledge and docs I couldn't think of anything worse, although it seems to work for you and it is popular on YouTube for some things (e.g. Unity game dev content seems be be pretty much 100% video based - if I just need to know how to set up something in the UI like character rigging or wheel physics etc, I often have to sit through 30min videos to find the 15 seconds where they show what buttons to click etc - if it was on a web page I could just skip right to it)
* Internal, non-technical users; what does the code do, why was it written, who currently owns it, when should it be run, how to run it, and what to do in case of failure. The more accessible, brief, and direct the better.
* Technical users; this is your README that usually doesn't need to be updated all that often. What is this code for? A quickstart for install/loading, dependencies, and the bare-bones set of functions, arguments, etc.
* Fellow implementers; the above README, but likely with a few additional notes of how the code is (high-level) broken up, and where to go for the most common things. This is where documented code is really good as well. I usually find the best code comments have always been A) NB: here's a drawn-out explanation of why the code does this, it's for a reason, do not question the code first unless you understand this and/or the above reason has changed, and B) in the future, you may want to do X, in which case you'll need to do J, K, and L and update M. Comments like those have saved me (from myself, even) so much grief and time.
* 3rd party users; this is where real documentation gets to be a monumental PITA and any company worth its salt will hire a technical writer or two. This is a very different skill than what's required for any of the above.
The biggest concern I see brought up again and again with documentation is that it becomes out of date quickly as soon as it's finished being written. This needn't be true. Internal documentation is just enough info for whoever is using it to know what it is, how/when to use it, what to do if it fails, and who to go to for more information or help.
Honestly though, the biggest problem with documentation has always been where it lives and how it's edited. Is it all repo READMEs and markdown? Are they google docs? A wiki/confluence? This is always where the breakdown happens. Programmers are comfortable with just being pointed to a repo and text files, while non-programmers want WYSIWYG docs somewhere central, which is the last place most programmers even think about. Wikis/confluence attempts to be a compromise that (IMO) no one likes. This - like task tracking - is a unicorn of software development.
Yup, I think if you are forced to use central WYSIWYG documentation, it makes sense to link to it from the readme in the repo. There's nothing worse than having documentation but being unable to find it or being unaware of it - it may as well not exist, and was a waste of time writing ;)
How do you test your documentation? Properly test it, ensuring that it answers many kinds of questions for those who are new to the topic, and who haven't already been working on this project for months?
If you're not testing it, then how can you consider it done? Would you do the same with your software?
The vast majority of documentation that I see these days is bad in multiple ways. Most common is lack of coverage for important topics or cases, and I'm not even talking about things like "why this product is built this way".
I'm talking about stuff like:
- An API providing all kinds of methods for manipulating "Fribblers", and when you look at the Fribbler class it just says "This is the primary class representing Fribblers." No idea what this means or how it fits into the wider API? Good luck!
- Parameters or properties appearing in lists without any explanation of what they mean
- ... and that's assuming those parameters are even listed at all, which (often) they're not
- ... especially when those parameters appear in other parts of the documentation. "This method will work asynchronously unless you've passed the "borgle" attribute to the Fribbler constructor." There's a borgle attribute?!
- And this is all just for basic usage of a product. Want to contribute, or run tests, or anything else? Nothing.
Documentation needs usability tests, same as anything else which is primarily designed to be used by humans who may not have seen it before. But it's hard enough getting proper UX testing for the product, let alone its documentation.
The problem is most people don't have this mindset. They expect documentation to be right, and when it isn't, they become frustrated and learn to avoid documentation.
* Can be learned from the code: Function A accepts a C-style pointer to a data array.
* Can be inferred from the code: Function A is called in an inner loop, and so it probably accepts that data array to avoid doing any memory allocation.
* Cannot be known from the code: Even though the data array is initialized to 0 in the current code, function A should not assume that will always be the case. That data array is intended to be used as persistent storage in a future version.
The first one is kind of pointless to document beyond what doxygen already gives you. The second is useful, but not necessary. The third is absolutely essential, because nothing in the current code can possibly tell you about the future intents for changes in the code.
* Cannot be known from the code: Feature F morphed into feature Q, and the function A doesn't really need that array anymore. Since nobody could tell why it was there in the first place, nobody removed it afterwards.
The next time someone has to make changes to function A, they'll be thankful for a comment or commit message that explains the first point above - as it'll let them complete the picture and realize it's no longer needed, so they don't have to worry whether their change is impacting anything else in the program through (mis)use of that array, but they can instead just go ahead and delete it.
The single biggest ROI I've seen on getting documentation written is to provide a template for developers to fill out.
Blank wiki pages are incredibly intimidating and developers can't always anticipate what people will want. Having a "madlib" style outline with things like:
- Where does this app run?
- How do you start it?
- Where are the logs?
- How do you common items X,Y,Z?
Takes your odds of documentation being written from near zero (in my experience) to at least 60%.
Who needs it?
what needs to be done?
who is the subject matter expert?
and so on. This makes it easier for the developer working on the task, keeps the description short and sweet.
Good software, bad doc is probably okay.
Bad software, good doc is downright bad.
Therefore, people/exec/management don't prioritize it.
If it were to be compensated with 100k, you would get the best doc ever.
We can't improve things if we don't incentivize. We don't incentivize because it's not that important.
Put another way, good software bad doc is a lot harder and more costly than good software good doc.
Totally agree with you otherwise.
It works. But it's hard to be consistent.
Let's say someone build a great feature with a lot of traction (e.g. money) but no doc.
Will you punish the team or celebrate the success?
"Sorry, your project make 20m, higher than any other projects in the company, but your doc is bad, so... you get below expectation rating this time".
There are tons of successful software with very little doc. So, my imaginary situation is very plausible. On the other hand, bad software with good doc rarely succeeds. But tbf bad software means unsuccessful software....
If you're designing, say, a RESTful API, it's a good idea to write a couple of client programs in different languages. See what kind of hell you would be putting your users through.
The idea generalizes, as well. Marketing is, sort of, documentation for the value proposition of your business. If you can't make the marketing work, maybe your business fundamentals need to be adjusted instead of hiring a “better marketer”.
I regularly run into the very issue you describe. I then update my designs.
To me, documentation is also tool to verify my designs.
Tools are much less a problem.
I suspect also that modern “agile” approaches work against building and maintaining documentation because developers are hyper focused on ticket level changes in short sprints.
Same goes to a lesser degree in writing tests. And when it comes to tests, devoting an entire sprint to increasing coverage seems to compensate, so perhaps a documentation sprint every few months might work.
Actually, the agile sprint approach also works against clean code based and discourages refactoring. So refactor sprints need to happen periodically.
I think I see a pattern here: current agile methodologies trade one set of problems for a new set.
People still did not liked writing documentation. They still did not knew how to write it.
At work, documentation gets written when the boss isn't looking. Corporate culture makes writing documentation taboo. The examples of great documentation I am most familiar with are written for open source projects where managers aren't around to hassle people for writing it. Particularly: mpv, ffmpeg, racket, emacs. In my career I have yet to encounter a commercial software project with documentation at this level.
Might be that the author is talking about a different kind of documentation, but I believe describing the behaviour of a program in sufficiently detailed fashion and justifying why the program behaves like it does are two very different things.
The former is the task of the programmer and the audience is likely other programmers while the latter is the task of a product manager and the audience is likely higher-ups.
As a programmer who needs to interface with a particular API, I will be very thankful for a documentation that tells me exactly how the data to pass to the endpoint has to look and what kind of responses I have to handle. If there are any particular quirks, constraints or special cases I have to be aware of when using the API, the documentation must explain those as well.
But to be able to use an API, it's not necessary to know the exact decisions and tradeoffs that explain why the quirks and special cases are as they are.
You need documentation to describe the intent that is not present in the code, i.e., why something is the way it is.
No it isn't.
Code is a series of steps that in the right environment will lead to a particular behaviour. Code doesn't (automatically) tell you what that behaviour is - even less if that behaviour is also the intended behaviour.
You can have "self-documenting code" to some extent, but even this code is often low-level, spread out over dozens of files and has to handle various cross-cutting concerns which are usually not of interest to you.
This is why command line tools have manpages, even if the audience are programmers and the code is open source, so a user could theoretically learn everything by looking through the code.
> A disorganized pile of classes and methods in code may work – a pile of work of words and paragraphs won’t work. Writing HAS to be clear if it is to be of any use. Code will be accepted (to some extent) as long as it does its job.
This suggests to me that the problem with writing documentation isn't that writing in itself is hard. It is that it is hard to write clearly about badly organised code. So the average programmer can get his disorganised pile to compile and pass the tests, but he can't clearly articulate, in speech or in writing, its organisation.
It's similar to the problem of naming things. If it is hard to find a clear and precise name for a class, it is usually because the purpose of the class isn't clear and precise.
So my suggestion is to write the documentation in advance. If the organisation of the code is very hard to express in plain English, then it is because the organisation of the code isn't very well thought through in the first place, and should therefore be worked on some more. And that is easier to do before a lot of code is written already.
Another critical mistake is expecting devs to cover writing the documentation that explains the deep contextual intricacies of the business logic and reasoning for said logic. Big mistake. Your docs should cover the code and how it can be operated. Anything else is why we have project briefs, strategies and other documents and meetings.
So writing documentation isn’t hard. It’s just more and more devs are coming from a willy-nilly-web-search-when-you-think-of-it background with no formal organizational skills or experience.
Most of what is written in doc-blocks above your function should be generated. Everything else is operational information.
The point of documentation is to communicate to others how to keep developing a code base - what is does, how it does it etc. What form the documentation takes can be fluid, a full fledged wiki or a single readme.md file can fulfill the same role just as well! Some documentation is better than nothing, so start small and then improve it over time.
Done right, it’s the final abstraction to the code: The whys and the hows, and effectively and gently guides the developer from epic/functional/spec/user requirements to the underlying design & implementation.
And by god, less is more; and more maintainable.
It brings it under source control and if the person reading it doesn't know markdown they likely shouldn't be reading it anyway.
It's a little bit of work on my part keeping that bridge up to date but that should (imo) be part of a leads job.
Documentation is a task that is never trivial, but it can be made bloody hard, or not, if you optimise for that. If you ignore documentation as a priority you're optimising for everything else, which implicitly breaks documentation.
But it doesn't have to be impossible, if the trivial aspects as designed to be minimal and the impact on documentation is allowed to dominate other impacts.
https://rant.gulbrandsen.priv.no/udoc/trolltech-documentatio... is relevant, even if most documentation isn't developer documentation. (It's about the Qt developer documentation, which IMO is/was the best developer documentation ever written and maintained by a small team, and no big team has ever done much better either. The hard thinking and work on that was mine.)
The key is that if documentation has such a low status that any other consideration can override it, the result will suck. And if documentation has such a low status that the writing tools suck, so will the result.
your manager will never give you a raise because you wrote nice documentations, in fact, he/she might think you're wasting time for not doing bugfixes or features development.
as long as documentation of code becomes one factor to evaluate the developers, with rewards somehow, things will change immediately.
I never felt doc is a technical problem, it's purely management for this one, it has been neglected for too long.
It just requires time, and I would be happy to spend that time (I love writing, whether docs or just thoughts). As long as there's no ticket for it (approved by a stakeholder and assigned to me by the micromanager), I can't clock hours on it, and if I'm not clocking hours on a ticket, I'll eventually get an angry call..
It's not just lack of incentives, it's disincentives.
Getting onboarded in a new project and having zero clue why X is written like that, why is Y is where it is and why Z is using a 10-year old thread-pool scheduler that is grossly inefficient. And you have to deliver feature A and bugfix B and you might collapse the house of cards and of course, critically important pieces of institutional knowledge are missing.
Eventually you do find out everything you need since you're not dumb and are a bright programmer, but you've lost weeks or maybe even months. The business have lost money because they basically had to give you anywhere from 1 to 3 full salaries just so you can catch up. And it's not even your fault, it's the last person's.
So I can't sympathize with "it's hard" at all. So what, dude? It's part of your job. Do it well. Nobody hired you to only do the easy stuff.
But this does outline the somewhat introverted, almost autistic nature of many programmers. When it comes to writing good docs most of them give up because that requires good and clear articulation which they don't possess. Or they find it "boring".
But they'd still curse if they found an obscure GitHub repo that could help with their their niche problem and find out that it has zero explanations or code comments.
And the guys who have it are the "10x devs" in that joint.
>Or they find it "boring".
Or, it doesn't count much towards your annual performance review so then why bother if you have enough stuff on your plate that does count towards your performance review.
When was the last time someone got promoted because they write really, really good internal documentation?
Let's face it, most web facing SW nowadays is like fast-food. Investing tons of time in writing quality documentation would by like a triple Michelin star chef writing a 20 page article about a doner kebab.
Oh I agree that most managers have no clue about this metric so doing it well will likely mark you as the slowpoke of the team.
The way I address this is that I budget the time for those "extra" activities beforehand. I just find it a professional courtesy to leave good docs for the next person after me -- or new hires while I am still there.
Not sure there's a way to actually incentivize programmers to write good docs.
Just giving me an URL with 50-100 pages of docs is not good enough. Give me something like "when you are just starting", "when you want to tackle a ticket involving X" or "when you need to edit the deployment script" etc.
In my last job the architect was always irritated with me because he wrote a bunch of docs but never organized them or just gave a proper small index -- seriously, just 15 lines of text with links so you know where to click at the start would have been enough! -- but then somehow the team was at fault for "not reading the docs".
So there's a balance. I don't appreciate being given a book and being told "figure it out", which is what happened in my last jobs. Sigh.
Having a small page with starting pointers I always found priceless and is what I do in my work and I've had people contacting me 5 years after I left the job to thank me for it.
As I said, I write good docs, but no-one will read them until they have been caught out 3 times asking obvious questions had they gone to the doc first. If I am not around, I know the docs will be abandoned immediately despite it representing a tome of hard won knowledge that saves an incredible amount of aggregate time from never needing to figure out how to do the same task twice.
It's not laziness if it's efficiency, or love.
A lot depends on the project size and expected lifetime (honest expected lifetime). But you can look at it from another perspective: the most basic internal documentation, like commit messages explaining why something was done, interface-level comments explaining what a function or class does, internal comments explaining the tricky bits of implementation - they all increase velocity of product development. So it's a good thing to do on team level.
(But it's kind of a "pay it forward" thing. You may not benefit much from your own comments, but you'll be thankful for the ones your co-workers leave.)
It's not the writing docs is hard, but that it takes a lot of time. I can write great docs, but it easily takes 50% of my time relative to code. The quality falls off pretty hard too -- my half-effort docs are pretty bad, like maybe worthless?
Obviously, there's a baseline level of, like, just commenting code which some devs still complain about, and that's absurd. But I think we need to be better at getting other people to value docs if we want them to be written, because they take time and effort to produce, it's a tradeoff like anything else in building software.
Businessmen get this stuff quite well. But I feel very often nobody explains them the situation.
But I've often found other devs can be your worst enemy here -- they rely on esoteric knowledge to build defensible moats around their seniority. Harder to convince execs about firing their "star" 10xer. Ultimately, this is why I think we need compiler assistance so that stuff like docs can be enforced in CI unilaterally.
Sadly you are correct. Job security and thus gatekeeping are the higher priority.
So yeah, yet another case of perverse incentives. :(
> Ultimately, this is why I think we need compiler assistance so that stuff like docs can be enforced in CI unilaterally.
Completely agreed, plus declarative programming. At 41 I am already sick to my stomach about having to manually write boilerplate. Tooling helps only a little and is hugely overrated; so what if the tool generates skeleton controllers et. al.? 90% of what you know should be there is yours to do anyway.
But that's a huge tangent. :)
I think we're going to go down a more personal road, start caring about who reads what, and just write what would help out, initially, and as reference. Lots of projects on Github do this right, the popular ones, as they convey meaning much better than their competitors. Such examples stand the test of time too.
Lisp and Smalltalk somewhat succeeded, but only for single user systems.
Two questions remain:
Firstly, does that land exist?
Secondly: if so, how do we get there from out local optimum that many, many programmers spend decades on to build higher and higher?
I've already resigned to the fact that any changes in the codebases I tend to work on involves spelunking through past commits, trying to git-blame my way into knowing where some suspect feature came from (and thus who to ask to explain it to me).
But few things annoy me more than when, after an hour of poking around and following code being moved across files, I finally arrive at the commit that introduced the thing I'm after, only to discover that the entire commit message is "refactored $foo", or "fix $blah". Oh, and the commit touched 20 different files, implementing 3-5 different things, and the author left the company a year ago.
So if you aren't doing it already, then for the sake of everyone (including yourself few months from now): please, write descriptive commit messages, while everything is still fresh in your memory. By descriptive, I mean at least a bullet point list of everything that was changed, and why. Even if it means repeating some of the stuff from a ticket or a discussion somewhere - because none of these things will be available or easy to find few months later.
Something like:
Add feature Foo
This commit implements feature Foo, as per ticket #12345:
option $foo controls whether or not Flux blergs or blargs;
in the latter case, $this and $that will happen.
* Configuration files have been updated with the new paramter.
* Flux Controller no longer looks at unobtanium to determine
the type of blerging to perform.
* The above implies that checking Flux for the type of blerg
is now speculative, and should not be relied on in the future.
* A new utility Asdf has been added; it provides common functionality
for blarging.
...
Etc. You get the picture. It's quite easy to write a message like this when committing - it's essentially a polished brain dump. And its usefulness will be immense the next time someone has to work in this part of the codebase.I reserve those bigger texts for PR descriptions.
I found those to be a nice balance, most of the time.
What people can do it help allievate the gaps, but sadly, they're not geeting much help from managers and business people this time 'round either.
Some even mentioned "code as documentation". In the end, they just kept finding justifications for not writing documentation or even proper code comments.
Three months after some solution was written, they couldn't explain the thinking behind it or even all the deep dependencies and magic return values because the person who had written the solution had left the team. Even then they were unwilling to see how documentation would have helped.
This repeated with every freaking team I have ever worked with. The only documentation any of those projects had was the one I created while figuring out the code base.
I observed a fundamental laziness in written communication in many developers and to this day I find it puzzling. I sometimes write down a draft of some solution just by myself, like I would explain it to another developer. More often than not, this helps me in highlighting inconsistencies or errors in my thinking.
But there are many legitimate reasons why one would clarify it as "harder" than programming:
- It requires a different skillset, namely writing.
- It is not uncommon for non-english shops to have a policy of documentation in english. That might be sensible, but complicates the task even further.
- In programming, it suffers from the same problems as math: Natural language is more often than not unsuited to express entirely abstract concepts, at least in concise and easily understandable ways.
- Conversely, natural language often lacks the necessary precision to talk about technical details.
- To alleviate all these problems with language somewhat, you might opt to use diagrams. Which requires yet another skillset.
- It requires time. And quite a lot of it actually. Usually more than you need for the actual programming task. This is why most managers care way less about documentation than they should: They know very well that it detracts time from actual programming tasks.
So sure, people tend to be lazy, but there are certainly good reasons why that happens more often in this area of our work than in others.
But all that started changing with react hooks on the frontend. With contexts and state going everywhere, it's really hard to document. How do you document a state machine that by definition is spread between multiple code locations? You can document a hook's purpose but it doesn't tell you anything about complex behavior. It starts to feel as hard as documenting code that has a bunch of mutable global variables.
If you don't agree, then imagine civil engineers which don't bother writing documentation, or mechanical engineers not bothering to do blueprints, or electrical engineers don't bothering to document schemata, properties and behaviour of components, etc. Would it be a work of an engineer?
The biggest problem with SW documentation is that people don't know how to do it properly and even why to do it at all. Mostly because people in universities also don't know how to do it properly and so it is not taught. As a result the documents are often a mix of useless prose with some incomplete and imprecise diagrams. That's why most people don't bother.
David Parnas makes it clear WHY and HOW to write documentation for SW.
If you wonder how good can documentation be then google "requirements document for A-7E aircraft". Barry Boehm has said that it's the best requirements document he has ever seen. I guess that it's still the best one!
When I talked to my successor about some piece of code a year later he told me how hard it was to refactor and (jokingly) that they pissed of a client breaking a bunch of features while refactoring it. I mentioned the documentation about it, but apparently he did not even notice it existed (seemed also not interested in it).
I guess my fault for not just saving it as markdown in our repo, but instead saving it in a document in our knowledge base (as was according to protocol).
And putting barriers in the way so that I can't code without docs just pisses me off when I'm demoralized. Make it take twice as long to code anything and I'm definitely thinking about looking for other work.
There are barriers, both psychological and real, against documenting changes that ride on an undocumented ball of mud.
The psychological barriers amount to, "what is the point". Why document some insignificant part of something that is documented, on the whole? For instance, imagine a windowing system that is mostly undocumented, except for the wonderful 15 page treatise on its scrollbars, because a compulsive documenter touched the scroll-bar code. Which was 13 years ago.
The real barriers stem from the problem that the documentation depends on other documentation, much like code depends on other code. If you document a small part of some undocumented whole, that documentation has nothing to refer to. There are no certainties it can rely on, provided by other documentation, no context. This attaches a barrier to the documentation: the first person to document anything at all in that system has to provide the context for that documentation, and start the process.
That barrier brings with it psychological barriers: the fear of the effort (how much time it will take to start the documentation effort) and the perception of futility: that nobody else will come on board, and so that will be the first and last piece of documentation ever written, effectively making it a waste of effort.
For these reasons, even programmers who write excellent, lengthy documentation for their side projects can become reluctant to document something on the job.
Developers working on an undocumented ball of mud might put their documenting effort into detailed summaries of their changes and the reasoning behind them, rather than into building a coherent description of the system: in other words, to write that documentation that is more likely to save them from any predicament caused by their changes, rather than to help someone else navigate the system as such.
Wow, almost sounds like some other aspect of a job a software engineer is required to do...
> If a developer doesn’t write documentation, their work still gets done.
If documentation is part of their job, it literally does not.
> Not writing doesn’t block shipping (at least not right away).
It should.
but for a lot of companies speed is king
Yes there are trade offs with everything you do in IT, one of them is creating a shit place to work in the name of speed.
It might work for a little while but eventually you're going to realize you're shitting where you eat.
Small startups seem to reach this stage eventually and in big companies, management is acutely aware of it, and breaks every attempt at correctness-over-business-rationality, under the teary cries of the autists, sometimes :D
Too much perfectionist? You will enjoy the journey, but probably won't reach your destination.
Til I realised it was a false dichotomy.
I don't want to work for a company that puts its need above mine. That company isn't worth my energy.
The correct decision is to take an approach that involves producing quality code and documentation as you go.
If you don't have the time available to do that then you don't actually have the time to do that piece of work.
Doing so regardless, or becoming expeditors is the worst thing you can do for a company. It creates a race to the bottom which in turn creates a god awful place to work.
This feedback loop continues to worsen as you struggle to hire and struggle to retain.
Eventually, you're fucking Comcast.
> It should.
Perhaps, but it doesn't.
>It should.
The rub is that it might not block what's currently being shipped. But that debt can come back to introduce headaches and delays for the next ship.
Which I think is the real problem. Writing/modifying code can't be ignored; the resulting behavior of technical systems absolutely depends on doing that.
You can argue that the desired behavior of human system also depends on good writing and you're correct. But the connection of the input and output is much more opaque, the social conception of the role is focused on the behavior of technical systems, the incentive structures are therefore focused on the behavior of technical systems, so when there is more to do than can be done writing docs will not make the top of the priority queue.
If you're building an open source general purpose tool, or something else meant to be reusable and consumed by the general public then sure. But the vast majority of software we write has a very definite lifecycle of birth, maintenance, and death. For the most part, one team with continuous word of mouth knowledge transfer will be responsible for it. And by the time that team has moved on, the software itself will have outlived its' usefulness. In an agile environment like this, keeping any kind of documentation up to date to be meaningfully useful is almost impossible without a dedicated team member.
Suddenly you have a Pune team managing all environments including production, who have rather vague about yet another system thrown on them due to that smart idea called outsourcing. Sure they can change a thing or two, but corner cases can and often do bite hard. Code itself, while describing well what is happening, often doesn't contain much info about why. Or further effects of decisions. Full picture of whole integration involving 20 or 100 systems etc...
Another issue in huge companies spread across the globe is the ability to actually connect with relevant team, and their reluctance to share crucial info. A job security political game is not foreign to devs in some cases. I've had my request for source code of one of our internal security libs, the cornerstone of all of our inter-app authentication, refused with justification that its safer for the company to not share it even within company. Mind you, the .jar wasn't obfluscated at all so JAD got me to almost-compilable version so that effort wasn't even half-assed.
Man, I could spend whole evening telling stories how documentation can be great. Even incomplete, not completely up-to-date one can save your ass from time to time. And tons of time on top of that.
It's easier to maintain documentation when it's closer to the project. You can also automate a lot of its parts for your projects. You can create template projects and use tools like cookiecutter every time you create a new repo to have the basic structure in place. That's already half of the road.
It has three advantages:
- They are cheaper then programmers.
- They write faster then programmers.
- Unlike programmers, they produce well structured easy to read text.
And bonus: if you are lucky, they will be able to explain to programmers how to write better. They won't make them into James Joyces, but will make them learn a bit. It will take time and only some programmers will improve, but the technical writers has that effect.
Joking aside, documentation is great but it needs to be treated as importantly as the code itself. Treating documentation as a feature, rather than an afterthought or side effect, will allow it to get the funding and attention that it deserves.
First of all you now have 2 sources of truth, both rot and only one of them is the actual truth.
Besides that I expect us all to write code the same way so after you are onboarded and need to learn something you should just dig into the code. In fact your job is to dig into the code and iterate it.
Own that code even if you weren’t the last to touch it you might have to be the next.
Although I do agree that it is vastly underappreciated :/.
Recent example: https://libguestfs.org/nbdfuse.1.html
Not only for your external documentation... for all of it.
If you are afraid of the costs, do the math.
1 technical writer for every 20 developers.
They can help identify gaps in documentation, outdated documentation, etc. They can take care of the clarity, formatting and distribution. You can create a ticket about documentation and assign it to them.
Then, while many developers write excellent documentation... some other developers truly SUCK at documenting. Some people like to sound intelligent and their comments read like a choose-your-adventure monologue that cannot be read linearly. Or they use vague, ambiguous language, or overuse acronyms or abbreviations. Or they sign every piece of code they touch like a dog scent marking your entire code base. Or they use profanity, or they get offtopic or humorous... All of that is a distraction from doing my job.
The technical writer takes care of those problems for you. They can create guidelines for documentation so that people treat documentation with the respect it deserves.
> All of that is a distraction from doing my job.
What job would that be? Do you actually have one?
For privacy reasons as this is indexed in search engines and comments cannot be deleted after 1 hour, forever.
> What job would that be? Do you actually have one?
I do, and it's none of your business.
If you want to participate in a community with an expectation of real life identity go have your discussions on Facebook or whatever.
Is technical writing part of your interviews? do you hire, promote or fire people based on technical writing performance? Is documentation taken as seriously as other code deliverables?
Why paying an expensive senior developer to maintain documentation in a non-commited way when you can pay a technical writer to do it better and for cheaper than the engineer can? And with real ownership and accountability over documentation, unlike the engineers.
Technical writers are cost efficient and pay themselves very quickly.
It was still worth it.
When I first started out I would keep big centralized documentation stores. If a project had a dedicated wiki then I'd use that, but if that wasn't present I'd throw together something on my internal note taking like Obsidian. The downside of centralized and detached documentation is that it's hard to check per pull request if it's been updated, so it relies on regularly fallible human processes. Second, code and architecture tend to drift, and it's difficult to stay on top of that drift with a centralized doc store.
I then gravitated towards in-repository documentation. I'd open up a /docs folder and either include a static site to be run locally or configured to run on the web. I haven't seen a ton of downsides for this approach other than that it will skew respiratory metrics if you keep them. Changes in the docs folder can be prompted and checked for in pull requests.
The only potential downside is when your software spans multiple repositories of different types. A deployment repo here, code repos there - have one store of your documentation in the application repository means you treat most (if not all) other repositories as generic and document them as such so they neatly fit into your software docs.
None of this even begins to touch on documenting inline, which is fairly key to maintaining good code. For all the churn and hand-wringing I see about when to document which is often phrased as when not to document, this is the chief barrier I see software engineers hit their head on. When you're working on a package / module / library it's easy to substantiate lots of implicit context that's easy to admit during this process. I follow this pretty loose framework:
- document inputs and outputs
- document error conditions
- document package purpose, intended use
This direct documentation should then be backed up by more implicit documentation like variable / function naming conventions and tests. Testing is all about maintaining contracts; not attaining "coverage". Though it is possible that tests are not only reinforcing trust for end users; I do generally trust tests in PRs but only so far as I know I won't break my users as opposed to being "bug free". Really thorough testing that instills my confidence involves other methods like fuzzing.