This is an HTML rendering of a working paper draft that led to a publication. The publication should always be cited in preference to this draft using the following reference:

This document is also available in PDF format.

The document's metadata is available in BibTeX format.

Find the publication on Google Scholar

This material is presented to ensure timely dissemination of scholarly and technical work. Copyright and all rights therein are retained by authors or by other copyright holders. All persons copying this information are expected to adhere to the terms and constraints invoked by each author's copyright. In most cases, these works may not be reposted without the explicit permission of the copyright holder.

Diomidis Spinellis Publications

© 2000 IEEE. Personal use of this material is permitted. However, permission to reprint/republish this material for advertising or promotional purposes or for creating new collective works for resale or redistribution to servers or lists, or to reuse any copyrighted component of this work in other works must be obtained from the IEEE.

Practical Programming Advice

Diomidis Spinellis

The Pragmatic Programmer: From Journeyman to Master by Andrew Hunt and David Thomas, Addison Wesley, Reading, Mass., 2000, 0-201-61622-X, 321 pp., US $34.95.

Early in my programming career, I was lucky to come across Brian Kernighan and P.J. Plauger's Elements of Programming Style (McGraw-Hill, 1978) and Jon Louis Bentley's Programming Pearls (Addison Wesley, 1985). These books deeply influenced me. Since 1988, when the last volume of Programming Pearls was published, no book has matched the insight and empathy to programming of those works. Although Elements of Programming Style is a classic, its RATFOR (rational Fortran) examples made me hesitant to recommend it to colleagues and students.

Fortunately, the last two years have blessed us with a new edition of Programming Pearls, Kernighan and Rob Pike's the Practice of Programming (Addison Wesley, 1999), and now Andrew Hunt and David Thomas's The Pragmatic Programmer ( The progress of technology has brought with it new tools and approaches. Scripting languages, client-server computing, graphical user interfaces, integrated development environments, object-orientation, Web applications, and Internet time all provide new opportunities and challenges for today's programmer. The Pragmatic Programmer addresses these issues and more, making the authors' experience accessible to all programmers.


The book targets those who know how to program and want to improve their skills. Structured as self-contained sections, it can be read in random order. This lets readers selectively read and apply sections most pertinent to their situation. For example, some sections assume knowledge of Perl. Because the authors rightly consider plain text processing an important skill for addressing complexity, readers can read those sections when they have learned Perl (the authors recommend learning one new programming language each year).

The authors typically condense their discussion of many topics in the form of a memorable one-line tip. These span from the functional, "learn a single editor well," to the practical, "coding ain't done till all tests run," to the deep, "abstractions live longer than details."

Hunt and Thomas have a talent for making concepts accessible and for motivating readers by using inspiring analogies. Revision control systems are fittingly compared to an "undo key" that spans an entire project's lifetime; all programming artifacts, not just source code, should therefore be placed under revision control.

On the subject of refactoring-which both in academia and industry has not received the attention it deserves-Hunt and Thomas assert that software construction shares more common traits with gardening than with building construction-a recurrent analogy in software engineering circles. Plants can thrive, but they need pruning. Minor adjustments can make the garden more aesthetically pleasing, but activities such as monitoring the garden's health, moving plants around, and fertilizing never stop.

Finally, when discussing specifications, Hunt and Thomas ask readers to write a specification for tying shoelaces, the morale being that some things are easier done than specified.


The range of issues Pragmatic Programmer covers is large-their common thread being ways to become a better programmer. Thus, we read about human development and social issues, design concepts and methods, a wide variety of tools and approaches for using them, defensive programming, techniques for programming in the large and in the small, requirements, and project management. The pragmatic advice offered similarly varies from the very technical (when debugging, you can sometimes determine the culprit for variable corruption by reading the memory in the variable's neighborhood) to the humane (sign your work and be proud of it).

Although many excellent books cover software design, most of them, written by the very people behind a specific methodology, are necessarily narrow-focused. Refreshingly, we can turn to Hunt and Thomas for a broad and accessible anthology of approaches that work. For example, they suggest when to structure an application around services, offer details on when and how to implement a model-view-controller structure (mind you, not just for graphical presentation), and explain how to use blackboard techniques.

By now, we all know the problems of the rigid waterfall model development processes; it is encouraging to see that the authors provide concrete advice on how to incrementally develop software. The tracer code approach they advocate is based on the development of architecturally complete-if not fully functional-code for demonstrating and concept-testing a software system. (The approach gets its name from another analogy: the tracer bullets used to identify a weapon's firing direction). This development mode-also advocated in a slightly different form by the Extreme Programming approach ("implement the most important features first")-complements rapid prototyping as a way to obtain early feedback during development.


The text is accompanied by a number of interesting exercises and aptly termed challenges. It was difficult to resist the temptation of thinking of an answer and comparing it against the one provided at the end of the book. (Which has a higher bandwidth,: a 1Mbps communications line or a person walking between two computers with a full 4GB tape? In your answer, document the constraints used.)

To keep the volume of the book manageable, many concepts and ideas are presented in a cursory style and some examples are rather contrived. I got the impression that the authors have enough experience to fill two books-one for each of them. Instead, as the next best thing, they provide references to practical books and pointers to free tools and documentation available on the Web. A selective bibliography complements the material offered. Although the books I mentioned in the first paragraph and Andrew Koenig's C Traps and Pitfalls (Addison Wesley, 1988) are unfortunately missing, the annotated bibliography can serve as a shopping list for populating a budding programmer's bookshelf.

I often found myself nodding and smiling while reading the book; the authors have successfully mined nuggets from the current programming practice field and made them available in an accessible and enjoyable form. I will certainly recommend this book to people whose code I will have to read or use.

Diomidis Spinellis is an assistant professor in the Department of Information and Communication Systems at the University of the Aegean. Contact him at