What Makes a Good Programming Book?
When I was about fifteen I sat in my room and read CODE by Charles Petzold. It changed my understanding of what a computer was and inspired me to go over to my desk and sit down at mine and try and get it to do stuff.
What made that book so effective? I think it was the focus on real life and a lack of cute analogies, combined with my own state of mind at the time: I was ready to go beyond “computers run on ones and zeroes”, and find out how they actually worked.
I’ve made a handful of attempts so far to write down some of my own knowledge about programming, aimed at a similar audience. Something deep inside tells me I have something useful to share, and that it would be a waste not to share it.
A brief aside: related to this are two of my other interests, writing good code and writing good documentation. Both of these are subject to Peter Naur’s thesis in Programming as Theory Building, which holds that writing a program for a particular task involves building a theory about the nature of that task, and that some aspects of this theory cannot be transmitted in the form of source code and docs—they have to be re-learned, and will be re-learned differently, by the inheritor of the code.
Contemplating this for too long makes me feel vaguely claustrophobic: is there any way we can ever be sure we’re thinking the same thing as someone else? Or are we stuck in our own minds? But there are, of course, ways of verifying that we’re at least roughly on the same page, in for example whether or not person A can successfully call an API written by person B. We both get there eventually, but by our own routes.
One thing I’ve noticed about a lot of technical documentation and learning material is that it seems to presume exactly the thing Naur claims to rule out: an ability, even a necessity, for a written or verbal description to cause a transfer of a mental model from one person to another. (I think of Naur’s theories as mental models.)
My own frustration has taught me that this is often misguided, and Project Author’s clear and concise description of Project makes no sense at all: it’s good for summarising an existing mental model at a high level of abstraction, but not for building such a mental model in the first place. I’ve even experienced this with my own writing, going back to some extremely clear—or so I thought at the time—comments about how I’d implemented median of two sorted arrays. The comments meant nothing to me until I’d thought about the task again and rebuilt the mental model.
When I think about writing a book on programming, it occurs to me that a large part of the urge might be to obtain the satisfying clarity of my own mental-model-summary, and that the resulting book wouldn’t help others learn programming. Nevertheless, the urge is almost irresistible, and I’m encouraged by the fact that I myself have read a book about programming and it did help.
What else was good about CODE? I suspect a big part of it is that Charles Petzold realised that the existing books weren’t very good, and made a conscious decision to do something different. His goal for the book was to create something that not only looked like it described how computers worked—by containing a complete and correct description of their inner workings—but functioned as an enlightening read, by prompting the reader to build their own mental models. Petzold was thinking from the perspective of a layperson, and he didn’t let the clarity of his own mental models trick him into thinking that describing them was the same as sharing them.
Here are some concrete suggestions to help technical authors focus on allowing their readers to build their own mental models:
Explain the problem addressed by a technology from the perspective of before the technology existed. “Some people had problem x” is a lot more relatable than “Technology allows people to do y”. Explaining that Google was spending a lot of engineer time manually provisioning servers and wanted to automate some of the load, is a lot easier to understand than:
Kubernetes is a portable, extensible, open source platform for managing containerized workloads and services, that facilitates both declarative configuration and automation.
Emphasise the challenges faced by the designers and implementors of the technology, and the resulting design decisions and trade-offs. Having to work within constraints and choose between alternatives with different sets of pros and cons is a relatable situation, and being specific about what these trade-offs were helps to ground and contextualise the solution.
Give specific examples, especially when describing how the technology connects to other systems or the outside world. It’s easy to brush this aside as an irrelevant detail, especially when the technology is flexible and can be wired up in multiple ways—but making this concrete acts as a useful foothold for readers to begin to visualise how a technology works and where it fits in. Generalising from examples is easier than understanding general statements.
A common theme here is that the story of how a system was built is often much easier to understand than the resulting set of abstractions. It’s easy to forget the false starts and naive assumptions made as a beginner and to become convinced that the concepts and metaphors you build up, refine, and simplify over time just obviously make sense. To unfamiliar readers these will be at best opaque and at worst misleading, as high-level concepts necessarily rest on lower-level ones. People are great at recognising patterns and constructing their own high-level representations. We just need enough examples that we understand, and stories are a great way to give a bunch of examples in the form of a compelling and relatable narrative.
Notes & Further Reading
The idea that it’s possible to transmit a mental model to someone else by describing it in words is called “transmissionism”, and it’s so widely regarded as a fallacy that the word is used as a pejorative.
Rethinking Programming Language Tutorials by James Hague.