Dr. Dobb's Journal March 2000
Most writers who try to tackle the "how" of programming stumble over one of two stools. First, authors can want to be gurus so much that they convince themselves that liberal use of bombastic psychobabble, combined with exhortations to "think outside the box" or "find a win-win solution" constitutes deep thinking. Jim McCarthy's Dynamics of Software Development is a prime example of this kind of book (see http://www.ercb.com/feature/feature .0003.html). It reminded me of the French generals who assured their soldiers that their superior spirit would carry them forward to victory against the German machine guns in 1914.
A second way to fail is to write as if the world actually worked the way the author thinks it should. Authors with a mild dose of this syndrome will claim that Perl's syntax reflects the way people think about programming, or ignore the fact that formal notations are incomprehensible to the average programmer, much less the average customer. Extreme cases will remind readers that Galileo was persecuted, and leave them to draw the analogy. Kaner et al.'s Testing Computer Software is a refreshing counter-example to this kind of writing (http://www.ercb.com/feature/feature .0043.html). Kaner and his coauthors explicitly acknowledge that while testers often get blamed for bad software, they rarely get a solid spec, enough respect, or the time they need to do their job properly. Few books are as honest about real-world software development as this one.
Both of this month's books about the act of programming avoid these failures, although each one has its own of minor flaws. Andrew Hunt and David Thomas's The Pragmatic Programmer looks at working practices, and in particular at the things that programmers can do to make themselves more productive. The second section, for example, devotes a single short chapter to each of "The Evils of Duplication," "Orthogonality," "Reversibility," "Tracer Bullets," "Prototypes and Post-It Notes," and "Domain Languages." Other sections cover basic tools, defensive programming, metaprogramming, estimation, and team-related issues. The writing style is very clear, and the authors' points are solidly grounded in the real world.
One thing that moves this book from "very good" to "excellent" is the many short exercises it contains. These do a good job of illuminating the book's points, without getting bogged down in platform-specific details. For example, Exercise 30 asks whether a blackboard architecture would be appropriate for each of three different types of applications, while Exercise 35 asks for an estimate of the amount of stack space a tree-printing routine would use when applied to a million-element binary tree. I really wish I'd had a course devoted to this kind of thinking when I was an undergraduate. Even now, after 16 years as a professional programmer, these exercises had a lot to teach me.
However, nothing's perfect. To take a small example, one of the author bios on the back says, "Andy Hunt is an avid woodworker and musician, but, curiously, he is more in demand as a consultant." Gosh -- if I buy this book, will it make me a cool Renaissance guy too? More seriously, I agree that "[g]reat software today is often preferable to perfect software tomorrow" (pg. 11), but what about buggy, barely functional software today versus slightly less buggy and only slightly more functional software some time next quarter? That's the tradeoff that real programmers face more often.
More serious still is the book's bias toward the traditional UNIX command-line toolset. This is great technology, but the world has moved on. For example, Tip #50 says, "Don't Use Wizard Code You Don't Understand." It's apparently all right to use compilers (although a friend of mine still insists that he'll never program a machine whose instruction set he doesn't know intimately), and it's okay to write your own little languages, but third-party code generators are evil. I understand why they believe this, but I've been letting Visual C++'s wizards generate code for me for about four years, and I honestly believe that they make me more productive, even though I don't understand all of the code they create.
Despite these criticisms, I really like this book. It covers the same common-sense ground as Kernighan and Pike's The Practice of Programming (http://www.ercb.com/ feature/feature.0039.html), and does it at least as well. (I consider Brian Kernighan to be the best writer on computing around, so that's pretty high praise.) I think every college student about to start their first programming job ought to read one or the other, as should any professional who feels that they haven't learned anything new in the last year.
I had a harder time figuring out how I felt about Kent Beck's Extreme Programming Explained. Extreme programming (or XP) is a software-development methodology that has evolved to address the needs of small teams that are faced by vague, conflicting, and frequently changing requirements, in a rapidly changing environment. Some of its fundamental principles are:
Some of the things XP does not contain are:
In short, XP is a formalization of the way that many good programmers already work. This shouldn't be surprising, as its creators are recognized in the object-oriented community for their skills. Beck himself, for example, coinvented CRC cards, and has been an influential figure in the design patterns movement.
Now, on the one hand, there's no doubt that software engineering could use some fresh thinking. For more than 20 years, programmers have nodded their heads during lectures about "design first" and "document everything," then gone about their business as before. It's high time that software engineering's advocates paid attention to the lessons that public health workers learned long ago -- if the people you are trying to help won't adopt the solution you're offering, then you have to change your solution.
On the other hand, I think that programmers who aren't as good as Beck and his colleagues will view this book as a license to be reckless. "Analyze requirements? Bah -- we'll just start coding." "Design the class hierarchy to be flexible? Bah -- we'll just throw some code down, then refactor it when we need to." This might be more productive for someone who has Beck's insight into software architecture, and who has internalized good practices to the point where they are instinctual. Most of the programmers I know, however, would quickly find themselves caught in a morass of inconsistent class interfaces, passed-through parameters, and switch statements that don't quite cover all possible cases. I realize that XP practices such as prophylactic testing are intended to prevent this, but these have to be backed up by experienced judgment to be effective, and it is just such judgment that less reflective programmers lack.
As with The Pragmatic Programmer, I still think this is a good book, and well worth a few hours of every programmer's time. Beck makes a cogent case for the practices he advocates. In particular, he explains very clearly how XP practices depend on one another, and why some of the received wisdom of software engineering has outlived its relevance. If Steve McConnell is right -- if the gold rush really is over, and programming is going to become a regulated profession whether we like it or not -- then I think it's tremendously important that books like this one be written and read, so that the future of programming is shaped by more than just one orthodoxy.
DDJ