|The Pragmatic Programmer: From Journeyman to Master / Andrew Hunt and David Thomas|
|Reviewed by Tal Cohen||Thursday, 16 August 2012|
On the back cover, Ward Cunningham, developer of the world’s first “wiki” (anybody-can-edit) web server, writes: “If I’m putting together a project, it’s the authors of this book that I want. ... And failing that I'd settle for people who’ve read their book.” I sure hope Cunningham has a more serious candidate-filtering mechanism in place, since I, for one, am not even sure about settling for the authors.
You see, the problem with Hunt and Thomas’s work is that it is full of platitudes and is surprisingly shallow; “tips” like “Care About Your Craft” or “Think! About Your Work”. To make it even worse, the book is riddled by errors and poor recommendations.
Take the authors' choice of languages, for example. Sure, one should pick the proper language for each task. And the authors use C, Perl, Java, and more in their answers-to-exercises. But there’s little or no rational for what language is picked for each answer. Exercise 5 (p. 63) challenges the reader to implement a mini-language. The solution (p. 281) is in C, and suffers badly for it: the code limits the mini-language commands, by design, to a single character; has zero flexibility with accepting arguments (an int or nothing); and all for no good reason. The very same code, written in Perl or Python, would have been immeasurably more flexible and maintainable.
Lots of examples and answers provided by the authors will fail on real-world input. This is particularly bad as the authors pump the ideas of code-generation, DSLs, write-your-own compilers and meta-programming way too light-headedly, without noting the high threshold that should be applied to any of these techniques. As a trivial example, the authors' own sample code generator (question on page 106, answer on page 286) will generate broken code if any of the field-names in the definition file happen to be a reserved word on any of the target languages. Now, I don’t expect a small example from a book to be a perfect one, but they never even mention the possibility; code generation, in the authors' view, is just a stroll in the park. Trust me on this one: it isn’t. (I do have extensive experience in the field. At the time of writing, tens of thousands of lines generated with a code-generation system that I wrote are used on production servers in Google.)
At times, the authors fail to follow their own advice (perhaps they’re following the footsteps of Strunk and White’s stupid grammar advice). Consider, for example, Tip 13: “Eliminate Effects Between Unrelated Things”; this is explained as “design components that are are self-contained ... with a single, well-defined purpose”. But their answer to Exercise 8 (p. 283) includes a method, doTime, that calls exit(0) as a side-effect. Seriously?
The section on Metaprogramming is a disaster. The authors confuse “storing configuration outside of the code” with “metaprogramming,” which means something completely different (writing programs that write programs). And then, they confuse configuration data with “metadata.” I’m sorry, but keeping user preferences, or the server’s TCP port, in a configuration file does not make that data “metadata” in any way or form, even if the authors claim to use the term “in its broadest sense.” Even if we forgive the out-and-out wrong terminology, the example they picked for preferring configuration in text files parsed at runtime over settings in the code is a particularly sad one: Enterprise JavaBeans (EJBs). The configuration scheme for EJBs, which is praised by the authors, quickly became known as “XML Hell,” and in later versions, by popular demand of tired programmers, support was added for in-source configuration settings using annotations.
They manage to fumble even the basics. What they call “the single most important concept in testing,” that of writing a test for every bug discovered, appears not in the section on testing, but in the chapter on working in teams (which has its own subsection on testing). And then, they fail to mention that the bug-detecting test must be written before the actual bugfix.
I'd rather not go on with this -- the review is starting to look like a laundry list. Getting back to Cunningham’s words on the back cover: If he wants the people that have read this book, I want those who read it and found it to be a disaster.