# Doc-Driven Development by Seth Kenlon Programmers and project managers sometimes think the term "doc-driven development" means putting a lot of comments in code, or that it means working closely with doc writers as development happens. That's because it's hard to imagine how development can possibly happen *after* documentation, because surely documentation can't happen until there's something to actually document. Documentation is, traditionally, seen as a sort of journalistic endeavour. Doc writers are given some software, and they take it into the lab and poke it and prod it until they've figured it all out and write it down for everyone else to never read. This misses the all-important process that happens naturally when a developer, idly sipping coffee one evening, drums up an idea for an application. A developer may not realise it, but as the idea formulates, there's a kind of documentation happening already. Ideas don't just appear fully-formed with every detail mapped out in a tidy blueprint ready to be hooked up to lonely lines of code. Ideas happen gradually. Code is arguably an art form, so here's an analogy set in the art world. A still-life painting represents something in the physical world. But still-life starts with abstract shapes at first, and then gets refined into something recognizable, and then gets texture added, and shading, and so on. This process could be called self-documenting, because at each stage of the painting's life cycle, you have a snapshot of how the painting has progressed. ![Self-documenting art.](docs_painting.jpg) In code, these snapshots might be git commits plus really good comments. While that's great for other coders who drop in later and want to understand what part of the codebase is responsible for which task, it's not generally useful to the average end user. In the still-life analogy, this means that while the self-documentation of a painting might be useful to an aspiring artist, it doesn't do much for the intended audience. The end user documentation of the painting is actually the end result: the thing the artist looked at while painting is the fully-realised image that the painting is meant to capture. Should the "end user" of the painting ever wants to understand the subject of the painting in its truest form, the end user refers to the actual, physical object. Believe it or not, the same is true for code. The only difference is that the application being documented does not yet exist yet. But that hardly means you can't document it as if though it did. ## Writing the documentation for the application you want When you sit down to write an application, you have some idea of what you intend the application to do. I'll use the utility [trashy](https://klaatu.fedorapeople.org/trashy/) as an example, because it's narrow in scope: Trashy is a command-line trash bin. That's often exactly where a developer starts, but if you practice doc driven development, it's where your man page or user manual starts, and it happens well before you sat down to code. If your only mission statement is "write a command-line trash can", then your code is likely to go in whatever direction happens to hit you first. You may or may not know about the [Free Desktop](https://specifications.freedesktop.org/trash-spec/trashspec-1.0.html) trash specification, so you might not think, at first, to follow its scheme. You'd probably know that there's already a trash mechanism, so your first iteration of your code would probably just dump a file into the user's established trash bin without any regard for the associated metadata that ought to accompany it. But if you sit down and document it first, you're forced to think about minutiae. For instance, imagine this as the first draft of documentation for trashy: Trashy is a command-line trash bin. trash foo : moves foo to system trash trash empty : empties system trash Already it's more robust than the original notion, because it also provides a mechanism to empty the trash bin, rather than just sending a file to it. And the only reason it's there is because the act of documenting how a user interacts with your application forces you to think of the application from the user's perspective. It's a dry-run of experiencing the difference between painting something and actually hanging that painting on a gallery wall for other people to see. ## Documentation as a framework As you continue to write documentation for your command-line trash application, you eventually come up with other "obvious" expectations that you yourself, as a user rather than a developer, would have for such a tool. You think of conventions, like having the ability to list what files are currently in the trash bin, or even restoring a file that got moved to the trash bin by mistake (which, in turn, would probably lead you to the Free Desktop trash spec, educating you about the metadata you should be writing along with your files when they're moved to the trash bin). Better still, your documentation is now your pseudo code. Your application development has gone from writing code that gets thrown out when you do your first revision to having the skeleton of your code ready to build upon: while [ True ]; do # trash --help: print a help message if [ "$1" = "--help" -o "$1" = "-h" ]; then echo " " echo "trash [--empty|--list|--restore|--version] foo" echo " " exit # trash --list: list files in trash elif [ "$1" = "--list" -o "$1" = "-l" ]; then list shift 1 # trash --version: print version elif [ "$1" = "--version" -o "$1" = "-w" -o "$1" = "--which" ]; then version shift 1 # trash --empty elif [ "$1" = "--empty" -o "$1" = "-e" -o "$1" = "--pitch" ]; then empty # trash --restore: restore a file to original location elif [ "$1" = "--restore" -o "$1" = "-r" ]; then RESTORE=1 shift 1 # trashy foo: moves foo to trash else break fi done # more code here... ## Documentation as a roadmap This has been a simplified example, but for a larger project the principles are even more important, and often the docs come from somebody who isn't also the developer. The result is a more focused development cycle, because instead of rumbling toward a vague idea of an application, developers code toward a specific blueprint of exactly how an application is meant to work. Every menu, every button, every contextual menu, has already been mapped out in the imaginary application's documentation. All the developers need to do is fill in the code. ## Consistency Just as importantly, documentation tends to produce consistency in how an application works, because the internal logic is mapped out well in advance. It's easy to code one function as a button click during week 1 of an application's development, but then relegate an equally important function to an obscure right-click menu during week 8 when space in the UI is at a premium. It's harder to do that when you're writing documentation for something that has no real estate yet. It's all imaginary during the documentation phase, so you'll see the breach of logic in providing a button for one task but hiding a related task. It doesn't get left that way for long when all it costs to fix it is a quick rewrite of a paragraph, which is quite a lot different than changing several blocks of code across many files, and potentially reworking the entire UI that you already spent weeks perfecting. When you're just documenting, you can write anything you want; it's a low cost repair, and in the end it provides a better, smarter blueprint for developers to build toward. ## Test-drive a doc today Possibly the greatest thing about doc-driven development is that there is no barrier to entry. Any non-coder can invent a documentation for an application that doesn't exist, and it's surprisingly useful. The applications I've written in the film industry and education sector have all been designed by someone other than myself. Sure, there's still back-and-forth user testing and refinement of something that looked good on paper but ultimately didn't work quite as smoothly as the designer had hoped, but it's far less than something without a designer. And sure, there have been times when a non-coder dreams up something way out of scope and has to be reeled in, but then again some times it's led to the developer learning some new tricks to make something previously thought out of reach actually work. Whether you're a developer or just a user with some good ideas, sit down and drum up some documentation for an application that you'd like to see. Alternatively, write some docs for a wersion of an existing application that you think could be better. You'll be surprised at just how much it affects the way you think about software, intuitive design, and development.