Book review: The puzzling empathy of debugging
- If I Only Changed the Software, Why Is the Phone on Fire? (Lisa Simone, Newnes, 283 pp., 2007)
- Find the Bug: A Book of Incorrect Programs (Adam Barr, Pearson Education, 306 pp., 2005)
We absorb second-hand experience in different ways, but when it comes to debugging, this is often done through stories and anecdotes. You probably know them as “gripe sessions.” If you want to be trendy, call them “retrospectives.” Regardless, in any meeting of developers, there are always going to be a few tales of woe that break the ice, and possibly even melt it.
Part of what makes these stories resonate with developers is empathy: we’ve all been there in some form or another. Be it bizarre user behaviour, ambiguous specifications, developer laziness (not your own, of course…), or just a confluence of calamitous circumstances, if you’re a developer, you’ve probably seen glimpses of them all. They affect your day-to-day work, if not your livelihood, so it matters.
Such stories also tend to come with a healthy dose of cynicism and exasperation. Deep down, reasonable people know that there isn't a malicious actor out to make them deal with a horrible bug, but at the same time we all have to vent now and then, and the malicious actor antagonist is the easiest one to invoke (the inherent laziness of devs—but not you—at work again). Great debugging stories don’t place blame. The root cause of the failure is the moral of the story.
If I Only Changed the Software is full of great debugging stories. Simone does something unique in the world of debugging books: she adds characters. There is technical heft to the problems that keeps the logical part of you guessing while at the same time weaving in the stories of the development team, whose members actually develop as characters. It’s a marvellous bit of writing.
The stories are described as mysteries, which is accurate because each has a social element. Simone doesn’t ignore the team aspect of working through a difficult problem, and doesn’t succumb to the temptation of using the malicious actor antagonist. The technical solutions can be fiendishly subtle, are never superficial, and always engage the reader. Just the technical aspects of the stories make the book worth recommending. The fact the book incorporates social context sets it apart. Such context is realistic and important. It is the primary way Simone’s writing taps into that empathetic response. Never before have I read a technical book that captures the sense of working on a team as well as this one. It’s a poignant reminder that debugging doesn’t have to be a solitary activity and that the effects of actually spending time on it affect others. You don’t debug in a vacuum. It’s refreshing to read a book that puts you in a world where customer needs, financial restrictions, logistical barriers, and your teammates actually play a role.
The thing about mysteries is that they break down into smaller problems as you work your way through them. At some point you may cross the boundary from problem to puzzle. It’s a fuzzy border, admittedly, but I’m willing to go out on a limb and say that a puzzle is smaller in scope than a problem. Puzzles (decent ones, anyway) are self-contained problems, that is, you are given enough information at the outset to solve them.1
Barr’s book is just that: a series of (nearly) self-contained problems. There are fifty puzzles in total, in groups of ten per programming language: C, Python, Java, Perl, and the somewhat inspired choice of x86 assembly. Each language comes with a compact primer whose intention is to provide enough information to work through the puzzles, although their usefulness is a bit like being taught matrix multiplication and then saying, “Well, you should be fine for linear algebra.” Without previous exposure to a language, solving the puzzles in that language is tedious and frustrating.
The book pushes the reader to practice debugging “on paper,” that is, to find the bug by only studying the code listing as printed in the book. Before getting to the programs, it lays out some code reading techniques and typical things that often lead to code defects. As someone who has taught programming courses multiple times and has been programming for a while, I have no quibble with the advice. It's useful and accurate. But as I worked through the puzzles following the book’s rules, I wondered what the point to it was. It is a pedagogical tool? Entertainment? In the end, I was uninterested in the content. Even worse, the whole thing felt like a condescending way to artificially inflate the reader’s ego.
Consider the notion of debugging only using a specification and a code listing. This means that you do not get to run the program. At all. You do not know the outputs it produces for any input without working it out yourself. It’s your responsibility to know the precise semantics of every operation and manage the state space of the computation manually. The thing is, debugging code from just a specification and an implementation is a sucker’s game because it turns you into the computer. And you are not a great computer. The result is an artificially inflated probability for error. It presents a challenge, to be sure, but it’s a situation where a useful lesson is buried in minutiae and you wonder why you’re trying to extract it at all.
The practice of artificially raising the difficulty level of a coding problem by depriving the developer of useful tools has the deservedly disparaging moniker of “whiteboard coding.” Whiteboard coding is obnoxious because the stakes are phony.
There is nothing inherently wrong with debugging on paper. You’re going to have to stare at a code listing eventually. The problem is that you want to do it with as much information as possible so as to increase your accuracy. When you normally analyze a code listing for a defect you have some evidence of its existing behaviour: it works when you start with x but not with y, for example. In other words, you have something tangible to work from. Furthermore, those tangible inputs probably came from a system that affects you in some way, giving you a reason to care.
Therein lies one of the key shortcomings of Barr’s book compared to Simone’s: Simone’s puzzles have stakes; Barr’s don’t. By adding that emotional investment, Simone gives the readers a reason to try and figure out the solution. Barr provides none of that; it’s just a series of facts. While the debugging advice in his book is good and the puzzles are challenging, they aren’t fun. They’re a just collection of whiteboard coding questions.
Furthermore, Find the Bug does not reflect on the solution. There aren’t many lessons in the book, which makes for an unsatisfying experience. Good puzzles are a conduit for instruction. Once you know the solution, you may try to generalize the technique you used to find the answer, or look for the hints that you didn’t see if you didn’t get it. If you don’t find the bug in Barr’s book, you won’t get guidance as to why. The book is working from the position of whiteboard coding, that being a position of knowing something you don’t and waiting for you to catch up (and subtly admonishing you if you fail).
The reader’s goal, then, becomes not to learn, but to take pride in figuring out the answer.2 Once this happens, there isn’t much of anywhere to go except to hang the puzzle over the head of some other poor soul and wait for them to “get it.” It encourages a pyramid scheme of pretentiousness.
Find the Bug book isn’t a playful “Try to find out why this doesn’t work!”, but a sterile “Tell me what I know.” It’s technically correct, but who cares?
This assumes, of course, the user has some general knowledge of the domain in which the puzzle has been placed. Crossword puzzles, for example, don’t provide all you need up front: they assume the user has a reasonable vocabulary and a slightly creative way of reading clues. Granted, many semantic hairs could be split over this, but think of it this way: crosswords don’t make up words (despite what you may think) just to fill out the space.
There are more than a few programs that have more than one bug, so the answer isn't distinguished. That said, there is only one intended bug per program. That's the answer you're looking for.