The Pragmatic Programmer: The Best & Worst

“The Pragmatic Programmer: From Journeyman to Master,” 1999, By Andy Hunt & Dave Thomas
4/5 Stars

The Pragmatic Programmer is chock full of useful advice, well written and helpfully framed around 70 tips. Those tips touch on most aspects of software engineering: from developing yourself and coding/design practices to advice for the whole team. At 260 pages, it’s a very good introduction to a lot of software best practices.

And while most of the advice has stood the test of time well, a few bits seem outdated. Having the advice spread out among 70 nuggets can make it hard to remember, and some of the tips are simply reminders of allegories from the book, which won’t refresh your memory if you don’t already remember the book. For a book so easy to read and dense with information, though, it’s easy to recommend to those friends and to revisit yourself – probably several times.

“This book is a hard copy of the distilled knowledge of a couple of exceptional programmers, not some lengthy academic monologue about software engineering theory or the latest methodology.” – Darren Collins

“Honestly, though, I worry that the book is somewhat futile. It may be one of those books that you either understand and agree with already, or you never will.” – Steve Yegge

(Some of) The Best

Don’t Repeat Yourself (DRY): if you find yourself writing the same code or logic in more than one place – stop! Writing it in one place means that you have fewer hidden dependencies. But this goes beyond refactoring code – when you have revision histories in a file and in your source control, that’s repetition too. When you have information in documentation and comments, that’s repetition too.

Don’t Live With Broken Windows: The broken windows theory says that when things are already in a state of disrepair, people tend to allow more and larger infractions. Not living with broken windows means not letting bad code pile up – it will only lead to worse code in the future.

Separate business policies from requirements and interface details: While not one of the tips, in the requirements part, Dave and Andy mention separating the details of interface and business policy. So a request that the system have a tab which lets the user see uncompleted tasks past their due date has both interface details (the tab) which could change based on system convention, and business policy details (overdue -> incomplete tasks past their due date) which may change based on policies (maybe tasks without a due date can be overdue after a few months).

Care about your craft: One of Dave and Andy’s first tips is to care about your craft, and I think it’s an essential bit of wisdom. When you care, you’re always trying to understand and improve. When you care, your heart is in it and you want to do things well. When you care, you do things like read the rest of the book, and go on to read more books or talk about it with people. Caring about your craft is the fuel which drives your future. It was this tip which inspired me to name this blog “Gives a Hoot.”

The Worst

Use a single editor well: Of all the tips, the recommendation to become proficient in your editor by using it for everything seems to have aged the worst. While this might make sense in a land of vi and emacs, where one text editor is used for editing all text, it’s impossible to ignore the benefits of an IDE and the code-specific extensions that it can do (static analysis, integrated debugging, code search, etc…).

Write code that writes code & Don’t use wizard code you don’t understand: My unease with Dave and Andy’s advice on code generators probably comes from my own experience working with generated code. I definitely think there are times when it works well – Dave and Andy describe the generation process as part of the build, and I think that it works especially well when you need to use one model to generate code in multiple languages (Dave and Andy give the example of a database schema and object file, and it is certainly invaluable in things like Google’s protobuf or Facebook’s Thrift). However, code generators make it easy to produce huge amounts of code that isn’t well understood – maybe you understand it because you wrote the generator, but will people who pick up the project from you understand it? I like generators as a last resort tool – it’s very easy for them to go wrong.

Iceberg Tips: The Pragmatic Programmer is about breadth, not depth. There are many, many more things that could be said about each tip. Since it was published, there have been great, solid treatments of these subjects, and that leaves The Pragmatic Programmer as a handy introduction, perhaps The Original, but just a start. There is no further reading, though maybe that would age what is a timeless book. Maybe what I’m really looking for is some online, up-to-date guide with references for learning more.

Beyond the Book

Atwood reproduced The Pragmatic Programmer‘s Quick Reference Guide on CodingHorror. The quick-reference or the table of contents serve as good overview of what the book covers. If you’re curious, but not enough to put down money, Dave and Andy did an series of 10 interviews with Artima Developer in 2003, covering/repeating most of the book (The link goes to the last in the series, which links to the others). Dave and Andy revisit the book 5 years after its publication in a 2004 interview with O’Reilly’s OnLamp, and talk about what they’ve been doing since. If you still want more, Dave has a blog, though it’s quiet at the moment, and Andy does too, though the topics of The Pragmatic Programmer have passed from their front pages.

It is worth mentioning, and perhaps a fitting encapsulation of this review, that I received my copy of The Pragmatic Programmer as a gift from a colleague of mine who used to have two copies, but decided he didn’t need them anymore and gave them both away to the newest members of his team.

This entry was posted in Book Reviews and tagged , , , , , , , , , . Bookmark the permalink. Both comments and trackbacks are currently closed.


  1. Posted March 25, 2010 at 9:22 pm | Permalink

    It seems to me like some of the best ideas you listed could be easily transformed into a checklist for refactoring, eh? Just a thought …. when review the code, check these points, if you answer yes to more than 3 bullets, then refactor it :-D.

    I have a different viewpoint about generated codes though. Like all powerful things in the world, it could granted you infinite power, or infinite misery if you are not careful. I think the specific case that generated code bite us hard is when each developer generate his own code and checks in to SVN. And then you have to go through all the pain of merging them. I think what the two refers to was to use a build server to do the generation (this be the only official version of the generated code), nobody checks in the generated source and use the generated code as if it is a library. I think the best documentation for the generator would be its test methods (if you do TDD, that is).

  2. Aaron
    Posted March 25, 2010 at 9:58 pm | Permalink

    Hah! “Infinite power, or infinite misery”! I like it. Dave and Andy definitely referred to generators which are part of the build, and I do think that approach gets around my worst fears with generated code. I still have a hard time thinking of when I want to use generators to create code rather than use normal language constructs, or a factory which reads in a configuration file and makes an object. The only times I can think to use it are to avoid repeating yourself across languages (as with protobuf and thrift), and to generate the barest scaffolding so that you don’t have to memorize (as with ruby on rails or many IDEs).

    Maybe it really depends on the language (I’m thinking here of LESS, which generates CSS), but it seems like today’s major languages already have enough built-in mechanisms that you don’t need to go and create some program to duplicate your code at compile time.