Listening notes: The Pragmatic Programmer

The audiobook for The Pragmatic Programmer is everything that an audiobook, and especially everything that a technical audiobook, should be. I love to listen to stuff about software, but a lot of it doesn’t suit the medium well. A lot of thought went into this: the narrator is excellent, some passages are read by the authors, and the code snippets are adapted to the audio format with good judgment.

Satisfyingly, this is not just an authorial but a programming success; the book itself is used as a case study in how to use text as a single source of truth, how to parallelize parallel problems, and how to do the reasonable thing even if it annoys your publisher.

It’s easily the single best technical audiobook experience of my life.

The content is also excellent: this is a true revision of the original. It mixes “wisdom of the ancients” and “current expertise” far better than I expected it to. (Not all rereleased classics of programming literature hold up.)

I endorse most, by far, of what’s in the book. Two quick points of disagreement:

  1. Some of their recommended “descriptive names” (e.g., “buyer” for “user”) seem dangerous to me. I’d rather maintain a focus on what the thing is rather than what it’s doing right now in your code. My stock example here: if I’m writing a program to order pizza, and I currently order pizza on all and only Thursdays, I should still name the thing in my code pizza, not thing_ordered_on_thursday or thursday_pizza. In the buyer/user case, I fear that the code might change so that a buyer is also a shipping recipient, a notification recipient, or something else. Many problems are caused by names that are not descriptive enough, but many are also caused by things named according to accidents of their original context, not their real essences.[1]
  2. The authors repeat fairly standard advice about using the power of Unix pipes and generally about the power of viewing programs as extended transformations. I agree about the power of the paradigm, but I’m more skeptical about its limitations. Chaining together a ton of shell programs with pipes is almost impossible to test, and I think tests are valuable even in very small projects. Also, and relatedly, this usually requires intermediate values to be coerced into textual formats. That’s often fine (or even desirable–see the chapter on “The Power of Plain Text”), but very often I’d rather have a program pass structured (and tested!) objects around. Finally, and at the risk of offending functional-programming acolytes, the paradigm of viewing all programs as transformations can be a Procrustean bed. But that’s a longer argument.

[1] There’s a counterargument here that roughly goes: if a thing takes on other roles, it will be in a different bounded context, so the other name will be for a legitimately different object in a different context, and the original (more specific–e.g., “buyer”) name will after all have been apt. Perhaps such an argument is correct, but that’s not the argument the authors give.