Beyond the Four-Document Model
Been a while! Now that learntla is out, I can get back to life. Exercising, eating, sleeping, and most importantly, updating this newsletter. Word of warning, though: all the stuff I want to talk about is inspired by things I did with learntla. Like, for example, limitations of the four-document model.
The four document model, aka The Grand Unified Theory of Documentation, states that there are four types of documentation:
- Tutorials: A step-by-step lesson that gets a beginner doing something with your project. In TLA+, this would be setting up and running a simple spec.
- How-to guides: A guide on how to solve a specific problem. In TLA+, this could be how to model a state machine.
- Explanations: deep dives into a particular topic. For example, auxiliary variables.
- Reference: clear, dry technical descriptions. Toolbox model configuration options.
If you want to learn more about the 4doc model, divio has a good page. I want to be clear that overall, I think the 4doc model is a great starting point that helped a lot of people write better documentation. Also, as learntla is teaching a language and not documenting a library, the 4doc model doesn't map well.
That said, the 4doc model is limited, and we can do much better. Here are two kinds of documentation I added to learntla that aren't covered by the model:
Conceptual Overviews
All of the traditional types of documentation present isolated information, to help people build distinct concepts in their head. Expertise comes from seeing the interconnections between concepts. The problem with showing the "big picture" is that too much detail is confusing to beginners.
The solution, then, is a conceptual overview, which walks through all of the concepts at a very high level. The conceptual overview should be written for the lowest common denominator. Someone completely new to the system should be able understand it and not get lost.
Here's part of the conceptual overview I wrote for learntla:
First, we need to describe the system and what it can do. This is called the specification, or spec. [...]
The specification has a set of “behaviors”, or possible distinct executions. For the spec to be correct, every behavior must satisfy all of our system requirements, or properties. [...]
Once we’ve written a spec and properties, we feed them into a “model checker”. The model checker takes the spec, generates every possible behavior, and sees if they all satisfy all of our properties. If one doesn’t, it will return an “error trace” showing how to reproduce the violation.
Notice this doesn't tell us how to do any of these things. That's what the rest of the guide is for! All we're showing in the conceptual overview is what we're going to do.
(The conceptual overview I wrote is imperfect: if I update it, I should add in a quick explanation of an action: "Something that describes a way our system can change." Again, not a physical example of an action, just a sense of what it is and how it fits into the larger topic.)
In addition to helping beginners see the overall picture, it helps outsiders evaluate your topic. Most topics are presented in a way that's incomprehensible to outsiders: either it assumes too much existing knowledge or is too "business jargony" to give a useful signal. Click around a few technologies you're unfamiliar with and see how much of a handle you get from the initial pages, you'll see what I mean. Conceptual overviews form a good middle ground that's approachable.
(This is different from an "explanation" because those are meant for people who are already deeply involved with the tech, and cover specific topics, while the conceptual overview is meant to be more expansive.)
Examples
We pejoratively talk about "copy and paste programming" as something done by incompetent programmers who don't know how to write code from scratch. But everybody starts out incompetent with a new software. People find it easier to take an existing block of code and adapt it to their specific problem than to write a specific solution from scratch.
Further, people learn better from seeing examples broken down. Examples are physical and modifiable. You can experiment with them and see the outcomes. You can see how each part contributes to the whole. You can see how everything is used together in practice.
Most documentation already has examples, but only as part of explaining a topic. You know, the kind that showcases OOP with
class Dog:
def bark(self):
...
d = Dog()
d.bark()
The more useful kind of examples are the case studies, where the code is solving an interesting problem. It's also good to have some examples that deal with the "accidental complexity" of the real world. Take a CSV processor. What does the code look like when we need to make it much faster? What about when the CSVs have two different types in one field? Duplicate rows? Missing data?
(I like how case studies capture expertise. When you're solving a complicated problem you're more likely to use all your built up tricks, and then you can present those to the learner.)
Other Kinds of Documentation
Not as much to say about these rn:
- FAQs. The questions people have don't neatly follow the organize of your documents, and you need a page which just compiles everything you see in practice.
- Troubleshooting. The same thing as FAQs, except common problems that don't neatly fall into a single 4doc howto.
- Best practices. Not a howto because you're not showing how to do something specific, not an explanation since it's too broad, not a reference because it's partially opinion-based.
It's been so long since I did an essay I've forgotten how to conclude them. Have a nice day, I guess?
If you're reading this on the web, you can subscribe here. Updates are once a week. My main website is here.
My new book, Logic for Programmers, is now in early access! Get it here.