The Pragmatic Programmer: From Journeyman to Master promises to make you a better programmer with around 70 concrete tips covering many different aspects of software engineering. But while I would have hoped for 70 deeply practical and thoughtful tips, many of them aren’t really that great. Pragmatic Programmer lacks depth, and its age (15 years) means that some of its tips are not nearly as helpful today.
Some helpful gems
It’s far from worthless, though. First, it’s very nice to see that the authors show a passion for programming as an art and a craft (hence the plane on the cover, I would guess):
Conventional wisdom says that once a project is in the coding phase, the work is mostly mechanical, transcribing the design into executable statements. We think that this attitude is the single biggest reason that many programs are ugly, inefficient, poorly structured, unmaintainable, and just plain wrong.
Second, many of the tips are (as of 2016) still relevant. Before continuing my rant, here are a few concrete examples I found helpful and educational:
- Don’t be swayed by vendors, media hype, dogma, or formal techniques. Critically analyze what you read and hear and put it into the context of your development practices and capabilities. This advice definitely holds true today, even more so than at the time of publishing, what with new frameworks and technologies popping up every single day and promising to be the solution to all our worries and problems.
- Don’t program by coincidence. Think about your work. It’s easy to work on autopilot – even when programming. Always strive to constantly critique and appraise your work and your practices, and you’ll always continue to improve. Granted, this is one of my main philosophies for most things in life, but it was nice to see it in print in a form that can inspire others.
- Don’t live with broken windows. The analogy here is that just one broken window in a neighborhood can cause the rest of the tenants to care less, and the whole neighborhood soon falls into disrepair. The same thing can happen with code. Be relentless in cleaning up bad code. When lying around, it invites even more bad code and bad practices, which snowballs into a whole mess of horrible code that everybody hates and nobody wants to touch.
- Refactor early and often. This is common sense nowadays, but from other stuff I read I get the impression that this piece of common sense isn’t always translated into practice. Few things are more disappointing than practices everyone agree on but nobody actually does anything about. Of course, in the pragmatic spirit, one should never refactor just for the sake of it (which was one of my disagreements with Clean Code – “always leave the code cleaner than you found it” is a nice rule of thumb, but definitely not a strict rule).
- Abstractions live longer than details. Consider a requirement-oriented example: “Employee records should only be visible to their superiors” is not just a requirement; it’s mixed with business rules. “Employee records should only be visible to selected users” is a better requirement. The fact that the privileged users in this case are the employees’ superiors is a business rule which can change at any time. Implement it as metadata instead (e.g. as configuration) – you’ll be glad later on that you didn’t hardcode it into your design. But of course (and this is my opinion), as with the previous tip, abstracting everything just for the sake of it isn’t a great idea.
Too shallow and not entirely pragmatic
Here’s another tip, which in and of itself is highly pragmatic and a helpful reminder: You can’t write perfect software. Pragmatic Programmer tells you to write software that is good enough. But what is good enough? Not a lot of details are provided here. And this exemplifies, unfortunately, a general problem with the book: It doesn’t explain thoroughly why you should do this specific thing that certain way. The book is a mile wide and an inch deep – it simply covers way too many subjects (from tools to methodologies to teamwork) for its length to treat them with any significant depth. Some of their tips are even no more than platitudes, such as “remember the big picture” and “make a habit of learning new stuff”.
Furthermore, not all their tips are as pragmatic as “you can’t write perfect software”. For example, they say “use a single editor well”, by which they mean, rely on a configurable, extensible, and programmable text editor instead of an IDE. Sure, I guess this was more true 15 year ago, but even so, it’s not a very pragmatic attitude (which would be “use the best tools for the job” – which they also advocate, so, go figure). And today, it’s even less helpful. Most IDEs are so complex now that they provide vast productivity enhancements over vim or emacs. When I develop an Android app in Visual Studio, I just press the magical “Play” button to boot up an Android emulator with my app. Debugging is seamlessly integrated. If I connect my Android phone via USB to my PC, then the Play button magically installs and debugs the app on my phone instead. In Xamarin Studio, you can even do “hot reloading”, editing the app while it’s running in the emulator. I don’t even want to think about how to set all of this up properly if you’re coding in vim.
The lack of pragmatism actually goes deeper than just specific tips. “Pragmatic programmer” is portrayed as an identity, complete with specific, preferred practices – “pragmatic programmers do this and that”, they regularly declare. In my mind, that’s more dogmatic than pragmatic. The authors seem fairly opinionated, and while I respect their experience, I take issue with parts of their notion of “pragmatic”. Personally I consider myself pragmatic, but I wouldn’t hold “pragmatist” as a core part of my identity. I’m pragmatic about my pragmatism, I guess, and I wish the authors were, too.
In addition to the shallow nature and the “opinionated pragmatism”, Pragmatic Programmer also suffers from its age. A lot of the tips are irrelevant today because they’re taken for granted. Here’s some examples:
- Don’t repeat yourself (DRY). This should already be familiar to all programmers. If not, you don’t need this book to tell you – you’ll get this everywhere.
- No decision is cast in stone; plan for change. Agile, anyone?
- Write testable code. Even if everyone doesn’t take this as far as test-driven development, I think everybody agrees that writing testable code is good practice, seeing how it leads to less coupling and better separation of responsibilities in your code.
- Do user testing. Although they don’t mention it by that name specifically, what they advocate (in one example, spending a week as a fly on the wall watching your client at work) is essentially a form of user testing. And again, although not everyone does that today, everyone seems to agree it’s good practice and “would definitely do that if we had the resources”.
- Always use source code control. Can you name a single professional developer today who, in their right mind, would not do this? (This point also shows how the “Resources” appendix is outdated, since the now ubiquitous Git isn’t mentioned anywhere – Pragmatic Programmer predates Git by five years.)
- And, of course, my favorite: Use an editor with syntax highlighting. A snide comment on my part would be superfluous; I’ll just quote the whole paragraph:
A feature such as syntax highlighting may sound like a frivolous extra, but in reality it can be very useful and enhance your productivity. Once you get used to seeing keywords appear in a different color or font, a mistyped keyword that doesn’t appear that way jumps out at you long before you fire up the compiler.
Yep, gotta have that frivolous extra.
Take it with a grain of salt
There are even things I don’t fully agree with. For example, they strongly suggest writing scripts to generate code if that can make your code more concise, clean, and DRY. While it’s difficult to argue with anything that makes your code better, my gut reaction is that if you really need code generators to keep your code in shape, the language you’re using may be too limited, and you might want to consider switching. Of course, there are always exceptions, and this may also just be my limited experience talking. And again, this piece of information may simply be outdated – the languages common a decade or two ago were much more limited than the higher-level languages common today.
In general, you should treat Pragmatic Programmer as you would any other kind of practical advice: Sit up straight, listen closely, and take everything it with a grain of salt. If something seems logical to you, apply it to your own coding practices. If something does not, discard it (possibly after investigating a bit more to make sure it’s not a gem of advice you just didn’t understand).
If you’ve been coding for a few years and actively tried to seek out a bare minimum of information on best practices, much of the information will likely seem common sense to you. Pragmatic Programmer is an OK book, and not entirely a waste of time seeing how there are good pieces of information in it. I’m having a hard time wholeheartedly recommending it for $30–40, though.
I haven’t read many programming books (yet), but I already know this won’t make it above “suggestions for further reading”. It would seem that going from journeyman to master might require a bit more careful treatment of the various subjects this book covers.
If you’re looking for good programming literature, go read Clean Code instead.
Much of The Pragmatic Programmer is common sense today. The rest is rather superficial, though not without merit or the occasional gem.