Programming Books

Practical programming books—all recommended.

This annotated bibliography lists books in my reading order from most to least recent (which is close to date order). There's also an alphabetical title index on the right.

Only those books that I think are worth reading (and that I myself have bought and read) are included, except for my own books which are listed separately. All comments are about the specified print edition, not about the possibly mangled ebook or translated versions. Note also that there may be newer editions of some of these books.

  Alphabetical Title Index
• Advanced Programming in the UNIX Environment
• Age of Surveillance Capitalism, The
• Architecture of Open Source Applications Volume I, The
• Architecture of Open Source Applications Volume II, The
• Art of Multiprocessor Programming, The
• C in a Nutshell
• C++ Concurrency in Action
• C++ in a Nutshell
• C++ Software Design
• Clean Code
• Code Complete
• Coders
• Core Java
• Crafting Interpreters
• D Programming Language, The
• Data Structures and Algorithms in Java
• Design Patterns
• Domain-Driven Design
• Don't Make Me Think, Revisited
• Effective C++
• Effective Modern C++
• Exercises in Programming Style
• Fluent Python
• Freedom to Think
• GUI Bloopers
• High Performance Python
• Java Concurrency in Practice
• JavaScript: The Definitive Guide
• Learning Go
• Linux Programming by Example
• Mastering Regular Expressions
• OpenGL SuperBible
• Programming Rust
• Programming in Scala
• Python Cookbook
• Python Essential Reference
• Python in a Nutshell
• Rapid Development
• Refactoring
• Rust Programming Language, The
• Security in Computing
• Seven Concurrency Models in Seven Weeks
• SQL for Smarties
• Tcl and the Tk Toolkit
• The Tcl Programming Language
• Using SQLite
• Your Computer Is on Fire
C++ Software Design: Design Principles and Patterns for High-Quality Software
Klaus Iglberger (O'Reilly Media Inc; 2022)

I consider this to be a really excellent book—both for its design ideas and for its C++. It is aimed at experienced C++ developers who want to stay up-to-date and raise their game. I learnt a huge amount from this book and strongly recommend it.

Full disclosure: I was one of the book's technical reviewers.

Crafting Interpreters
Robert Nystrom (Genever Benning; 2021)

Crafting Interpreters is one of the most inspiring, enjoyable—and useful—programming textbooks I've ever read. The writing style is engaging and accessible, the emphasis strongly practical. Theory is provided when necessary, and clearly explained.

The first part of the book uses Java, the second uses C; but it doesn't matter whether you know either, the exposition is so clear you can easily translate in your head or at the keyboard into the language you're most familiar with.

If you want to create—or simply understand how to create—a language, DSL, or file format, this book will take you further than any other I've ever read. It certainly slays the dragon of first time programming language implementation.

Freedom to Think
Susie Alegre (Atlantic Books; 2022)

This book is essential reading for anyone involved with software development (programmers, designers, psychologists, managers, etc.). It clearly explains the practical and legal impacts of software (especially AI, social media, and online advertising) on users (both adults and children). It shows how our thinking can be influenced both for the purpose of selling products and political positions, and how the law can be used—and in some cases needs to be strengthened and extended—to protect our freedom of thought.

Learning Go: An Idiomatic Approach to Real-World Go Programming
Jon Bodner (O'Reilly Media; 2021)

This book is aimed at existing programmers of languages other than Go (or those who've been away from Go for a few years).

Written more than a decade after Go's 1.0 release, in addition to teaching the Go language itself, this book illustrates many useful Go programming patterns. For example, the book shows now-standard ways of doing Go concurrent programming, as well as how to make best use of Go's evolved features for modules, contexts, and error wrapping. And the book finishes with a short but useful introduction to Go's support for generics.

A genuinely useful introduction and guide to modern Go programming, this book also highlights Go's few misfeatures and how to avoid being caught out by them. Strongly recommended.

Your Computer Is on Fire
Editors: Thomas S. Mullaney, Benjamin Peters, Mar Hicks, Kavita Philip (The MIT Press; 2021)

This is a collection of essays designed to provoke thought and debate about the uses and impact of computing on society.

The essays range from those about the physical infrastructure—for example, the “cloud” may appear to be virtual, but actually runs on huge numbers of computers in very large power-hungry data-centers—to the human aspects. For example, no matter how many or how diverse are the children taught to program, if big companies primarily hire and promote those from a narrow spectrum, then the software they produce will likely only suit people like themselves.

Back in the twentieth-century, for most programmers, ethics was really just concerned with professionalism: being honest about timescales and what was possible and working to the highest standards ones abilities and the available tools and hardware made possible. But nowadays, the ethical aspect is much wider, from who decides how an autonomous vehicle should behave to all the topics covered in this book.

This book would be a beneficial addition to the reading (and debating) list for any undergraduate course that had any computing or management modules. Recommended.

The Age of Surveillance Capitalism
Shoshana Zuboff (PublicAffairs; 2020)

This book could usefully be read by every practicing and aspiring computer scientist, data scientist, programmer, and those who manage them. It will make you think about the work you do and for whom, about the interface between your work and ethics and law, and above all on the impact of your work on society.

Prior to reading this book I believed that when things went wrong (e.g., Google's collection of private WiFi data during Street View journeys, or Facebook's repeated selling of private data), it was due to genuine error or rogue “bad actors” as the companies' claimed. Now I understand that these things (done by Apple, Google, Facebook, Microsoft, Verizon, and so on) are matters of policy, and that lying about what they're really doing is standard practice.

Naturally, I don't expect anyone to take my word for it. I strongly recommend reading this book. It is easy to read and fully referenced so you can check its sources for yourself.

Refactoring: Improving the Design of Existing Code
Martin Fowler (2nd edition; Addison-Wesley; 2019)

This is an ideal book for less experienced or less formally trained programmers wanting to improve the quality of their coding.

The book is essentially a list of recipes that show how do do various code improvements in a reliable and systematic way.

All but one example is illustrated using JavaScript, but all the code is very easy to understand, and the ideas and practices are applicable to—and easily translatable to—any modern object-oriented programming language.

Each recipe is small, self-contained, and well explained. And here and there the author has injected tiny sparks of leavening humour. Recommended.

Coders: The Making of a New Tribe and the Remaking of the World
Clive Thompson (Penguin Press; 2019)

This is a non-programming book that is nonetheless worth reading by every programmer, would-be programmer, and anyone else involved with or interested in software.

The book provides information and insights into programmer psychology, into how and why certain groups are excluded or underrepresented in programming—and what the effects of this are. It also addresses some ideas for remedies. It examines the pressures that developers and software companies are under and the impacts these have on corporate behavior and the practical and ethical results.

This book is thought-provoking and full of ideas and facts about software developers, software development, and software companies. It will deepen anyone's understanding of how, why, and by whom software gets written, and what the consequences are. Highly recommended.

Core Java Volume I—Fundamentals
Cay S. Horstmann (Prentice Hall; 11th edition; 2018)

The Java language has evolved quite a lot since the 1990s, incorporating modern features like lambdas and generics. This book (and its companion, Volume II) covers the fully up-to-date modern language, as well as the most important and widely used parts of the standard library.

What I particularly like about this book is that it explains points of contention (e.g., how to implement equals()), and provides the arguments on the different possibilities and the rationale for the choices made in the book.

Another aspect I like is that in some cases the book provides useful code snippets or classes to supplement Java out-of-the-box. Overall, this book is ideal for programmers of other languages who want to learn modern Java.

The Rust Programming Language
Steve Klabnik and Carol Nichols (No Starch Press; 2018)

Rust is a modern language that can be used to create applications and systems of all kinds. The language uses aggregation and traits rather than inheritance. The Rust compiler does extensive code analysis to make it impossible to introduce data races in concurrent code, and generally eliminates whole categories of potential errors that C/C++ compilers are defenceless against. The compiler uses the LLVM toolchain, so produces fast-running executables. Rust's build tool, cargo, is a pleasure to use.

This book teaches Rust from scratch, but assumes some programming knowledge. It is Rust's official textbook and is freely available online. The early part of the book is a bit uneven—alternating between baby steps and being more demanding, but it does give good overall coverage of the language. The book goes beyond being a mere introduction in that it explains some subtle and important Rust features including interior mutability and key patterns of use, especially for concurrency. However, no mention is made of the excellent and easy-to-use concurrency provided by the rayon crate. The error handling coverage is barely adequate, with no mention of the error-chain, failure, or quick-error crates.

This book will be useful to anyone starting out with Rust. In addition to covering the language and glimpses of the standard library, it illustrates good Rust style, something not always obvious (for Rust or any language) simply by reading the documentation.

The Tcl Programming Language
Ashok P. Nadkarni (self-published; 2017)

This book covers the Tcl language and library. In addition it covers many useful parts of Tcllib (Tcl's standard library), and some third-party libraries. The coverage includes cross-platform differences and practical advice based on real experience with the language.

This is the first self-published book I've ever read that could be published as-is by a reputable publisher. Overall it is well-written and interesting. And unlike Ousterhout's book it covers Tcl's object-oriented features. (However, it doesn't cover GUI programming with Tk, so for that Ousterhout's book remains essential.)

Programming Rust
Jim Blandy & Jason Orendorff (O'Reilly Media; 2017)

This book teaches Rust to programmers of other languages. Given the dearth of good Rust books, this book is certainly worth reading. It covers the Rust language pretty fully, although it doesn't cover much of the standard library, or have much to say about third-party libraries. The book introduces the novel and advanced feature of “lifetimes” rather early, which would have been fine if the subject had been returned to later on to explain how and when to use owned and borrowed data in structs. The index is poor. Overall, this book is adequate for getting to grips with all the basics, and is sufficient to get people to the point of writing their own small programs. A lot more reading elsewhere will be required to progress further though.

Python in a Nutshell
Alex Martelli, Anna Ravenscroft, & Steve Holden (O'Reilly; 2017)

This book presents the entire Python language (2.7–3.6), many parts of the standard library, and some important third-party libraries. It is ideal for beginner/intermediate Python programmers who want to broaden their knowledge with a useful overview; and for those moving from other languages to Python. The book provides sufficient introduction to get started with many major topics in Python programming, and usually provides links for where to get further information. The coverage of Python 2.7 is unfortunate since it complicates and confuses the text in places.

Programming in Scala
Martin Odersky, Lex Spoon, Bill Venners (Artima; 2016)

Scala is a hybrid object-oriented—functional language for the Java Virtual Machine. The language itself is large and interesting. And this book is an excellent introduction. In fact, this book could be taken as a model of how to write a programming language textbook. The explanations are crystal clear using appropriate technical terminology (that's properly explained), and liberally illustrated with readable and understandable examples throughout. For anyone coming from a procedural or object-oriented programming background—and for anyone considering writing a programming textbook—this book is well worth reading.

Fluent Python
Luciano Ramalho (O'Reilly Media; 2015)

This is essential reading—in addition to the Python Cookbook and my own Python in Practice—for any Python programmer (beginner to intermediate) who wants to broaden and deepen their understanding of Python. The book is wide-ranging and interesting with the occasional flash of humor. It includes an introduction to using Python 3.4's asyncio module. The only weak area is the coverage of meta-programming which is rather short and superficial; but the rest of the book is really excellent.

SQL for Smarties: Advanced SQL Programming
Joe Celko (5th edition; Morgan Kaufmann; 2015)

On the positive side the book illustrates many useful, powerful, and advanced features of standard SQL, and is packed with interesting advice and information. On the negative side the prose is often poorly written and is littered with typos; and sadly, the typos extend into some of the examples too. Apart from the typo caveats, this book should be useful for anyone looking to move more of their code out of their procedural language and into pure SQL, and for anyone wanting to deepen and broaden their SQL knowledge.

Data Structures and Algorithms in Java
Michael T. Goodrich, Roberto Tamassia, Michael H. Goldwasser (Wiley; 6th edition 2014)

This is a well-written textbook ideal for computer science undergraduates or anyone else who wants to understand the design and performance of data structures and algorithms. Naturally all the examples are in Java, but the performance analysis generally applies to the same data structures and algorithms regardless of language. In fact, porting some of the code to another language would probably lead to an even deeper understanding. Although for those who like Java itself, there are plenty of graded exercises provided.

Effective Modern C++
Scott Meyers (O'Reilly Media; 2014)

Every programmer ought to read this book—whether or not they use C++!

If you use C++, you need this book because it explains all the major pitfalls and how to avoid them, as well as all the important best practices. It covers the type deduction rules, the use of auto, move semantics, smart pointers, rvalues, lambda expressions, as well as a bit of useful advice on concurrency. (For comprehensive coverage of C++ concurrency see C++ Concurrency in Action. And for more advice on C++ programming, much of it still valuable, see Meyers' other books, especially, Effective C++.)

If you don't use C++, you need this book so that you can show your boss all the reasons why it would be insane to use C++ to build reliable and maintainable software. It isn't that C++ can't be used for such purposes, but rather that is has become so complex and so subtle that only the best programmers on their best form can make full use of it without tripping up. For mere mortals, pretty well any other mainstream language will be a better choice not because of any limitations in C++ (it has few left), but because it is so easy to make subtle mistakes and so easy to write code that's only comprehensible to gurus.

Exercises in Programming Style
Cristina Videira Lopes (Chapman and Hall/CRC; 2014)

This unusual and interesting book takes a simple programming problem and presents over thirty different implementations, each illustrating a different programming style. This approach makes it very clear how the different styles differ, and the accompanying explanations help with understanding the trade-offs. The examples are in Python 2 and written in a very simple style so they are easy to understand and apply to any language. The book will be most useful to intermediate programmers seeking to broaden their toolbox of coding ideas and practices, on their way to becomming more advanced practitioners.

High Performance Python: Practical Performant Programming for Humans
Micha Gorelick & Ian Ozsvald (O'Reilly Media; 2014)

This book is mostly focused on Python 2.7 with a few remarks about Python 3 here and there. It is also geared up mainly to those using Linux. The book looks at the fundamentals—in particular, profiling and the use of Python's built-in data structures. It also introduces NumPy and Cython, as well as some lesser known technologies. The book will be of most benefit to two kinds of reader: those doing large scale processing on a single machine (e.g., big numeric computations), and those doing large scale processing more generally (e.g., using clusters or cloud computing). Apart from the early chapters which go into reasonable depth, most of the rest provides introductory material on techniques and technologies to get you started. A useful overview and a useful start for those beginning to get to grips with performance problems.

Seven Concurrency Models in Seven Weeks: When Threads Unravel
Paul Butcher (Pragmatic Bookshelf; 2014)

Ignore the "Seven Weeks" silliness—this is a really well written and interesting book that looks deeply into the major approaches to doing concurrency. The book covers all the pitfalls as well as showing the benefits, and is written in an accessible style that any moderately experienced programmer should be able to understand. The examples are in different languages since some approaches to concurrency are available only in particular languages, but are well explained and easy to follow even if you don't know the language concerned. This book serves as an excellent introduction to concurrency, although experienced concurrent programmers should also find much of interest. C++ programmers should also read C++ Concurrency in Action. Java programmers should read Java Concurrency in Practice; hard-core Java programmers might also enjoy The Art of Multiprocessor Programming.

Don't Make Me Think, Revisited: A Common Sense Approach to Web Usability
Steve Krug (3rd edition; New Riders; 2014)

This is a short and practical book on web usability based on research and experience. Applying the easy-to-understand ideas in this book will improve any web site of any size. (Based on the second edition.)

Advanced Programming in the UNIX Environment
W. Richard Stevens, Stephen A. Rago (3rd edition; Addison-Wesley Professional; 2013)

A thorough in-depth introduction to Unix programming using the Unix system call APIs and the standard C library. The book's examples are in C. (Based on the second edition.)

OpenGL SuperBible: Comprehensive Tutorial and Reference
Graham Sellers, Richard S. Wright, Nicholas Haemel (6th edition; Addison-Wesley Professional; 2013)

This is a good introduction to 3D graphics using OpenGL, suitable for programmers without prior 3D graphics experience. The examples are written in C++, but the OpenGL APIs are usually pretty faithfully reproduced in bindings for other languages (e.g., PyOpenGL for Python), so the book's examples can be used without too much adaptation.

Python Cookbook
David Beazley, Brian K. Jones (3rd edition; O'Reilly Media; 2013)

This book is full of interesting and practical ideas covering all aspects of Python 3 programming. I have two caveats. First, some of the ideas for improved efficiency only seem to work well for unrealistic examples. Second, some of the more advanced examples show what can be done—but not necessarily what one ought to do when writing maintainable code. Nonetheless, every Python programmer should buy and read this book.

The Art of Multiprocessor Programming
Maurice Herlihy, Nir Shavit (Morgan Kaufmann; 2012)

This book provides a thorough introduction to multithreaded programming, including small but complete working examples (in Java) that demonstrate all the key techniques. The last chapter provides a brief introduction to transactional memory, one of the hopes for a higher-level approach to threading that doesn't burden programmers with all the petty bookkeeping details that conventional techniques demand. This is not light reading, but worthwhile for those who really want to understand multithreaded concurrency rather than simply use it through their language's libraries. Incidentally, the links are to the revised reprint, I only have the original. For a more accessible introduction to concurrency (not just using threads), see Seven Concurrency Models.

C++ Concurrency in Action: Practical Multithreading
Anthony Williams (Manning Publications; 2012)

This challenging book covers concurrency in C++. It describes many of the problems and pitfalls that can afflict concurrent programs that use threading (regardless of language), and explains how to avoid them.

The Architecture of Open Source Applications Volume II
Amy Brown & Greg Wilson (editors) (Brown & Wilson; 2012)

This book follows the same pattern as Volume I (described below). And like Volume I it is interesting and useful, especially for those contemplating larger or multi-person projects.

The Architecture of Open Source Applications Volume I
Amy Brown & Greg Wilson (editors) (Brown & Wilson; 2011)

This is an unusual and valuable book. Each chapter covers a different open source application and is written by one of the application's lead developers. Each chapter gives a brief introduction to what the software does and then goes on to explain the overall architecture, the rationale for the key decisions, and concludes with a brief assessment of the project's successes and failures. Anyone interested in building larger scale software or working on multi-person software projects should find something of interest in this book.

JavaScript: The Definitive Guide: Activate Your Web Pages
David Flanagan (6th editon; O'Reilly Media; 2011)

This is an ideal tutorial and reference for JavaScript/ECMAScript. It is comprehensive and easy to read, and the examples work. The few bits of JavaScript used on this website are all based on ideas and examples from this book.

The D Programming Language
Andrei Alexandrescu (Addison Wesley; 2010)

D is a very interesting language. It is much easier to learn and use than C++ or Rust, yet offers many of the benefits of those languages, plus many additional—and useful—features unique to D. It is rather sad that D has not had the attention of other languages (such as the far less capable Go), and so D is not especially well supported either in terms of documentation or third-party libraries. Nonetheless for non-GUI programs D has much to offer.

Although rather old, this book remains by far the best book on D. It is well structured and clearly written in a good humored and accessible style. It is aimed at those who can already program rather than beginners.

Using SQLite
Jay A. Kreibich (O'Reilly Media; 2010)

Don't be put off by the “Lite” in SQLite—SQLite is a real database with excellent SQL support. SQLite is very widely deployed and is useful not only as a conventional SQL database but also as a single-file file store for application data. This book shows how to use SQLite to create, modify, and query databases. It also serves as a good introduction to SQL since it doesn't assume prior knowledge of SQL. In addition to being a fine tutorial, the book is also a good reference. SQLite is accessible to any language which can access C libraries (pretty well all languages). For example, Python includes built-in support for SQLite with its sqlite3 module; but I recommend using APSW instead since it is far superior, offering as much access to SQLite as C programmers get but through a nice Python API.

Python Essential Reference
David M. Beazley (4th edition; Addison-Wesley Professional; 2009)

The book's title is an accurate description. The fourth edition has been updated to cover both Python 2.6 and Python 3.0. Most of the book is devoted to Python's standard library as well as covering more advanced features such as extending Python with C libraries and embedding the Python interpreter into other programs. Personally, I find David's Python Cookbook more useful and interesting.

Tcl and the Tk Toolkit
John K. Ousterhout, Ken Jones (2nd edition; Addison-Wesley Professional; 2009)

This is the standard text on Tcl/Tk 8.5. Tcl is an unconventional, almost syntax-free language. It is worth learning about simply because it is so different from almost anything else, and the ability to write lightweight cross-platform GUI programs with it is a useful bonus.

(For coverage of Tcl 8.6, see The Tcl Programming Language.)

Clean Code: A Handbook of Agile Software Craftsmanship
Robert C. Martin (Prentice Hall; 2008)

This book addresses many “tactical” issues in programming: good naming, function design, refactoring, and similar. The book has many interesting and useful ideas that should help any programmer improve their coding style and make their programs more maintainable. The book's examples are in Java, but in most cases they are applicable to any object-oriented language (and often to procedural languages too).

GUI Bloopers 2.0: Common User Interface Design Don'ts and Dos
Jeff Johnson (2nd edition; Morgan Kaufmann; 2007)

Don't be put off by the slightly whimsical title; this is a serious book that every GUI programmer should read. You won't agree with every single suggestion, but you will think more carefully and with more insight about user interface design after reading this book.

Java Concurrency in Practice
Brian Goetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes, Doug Lea (Addison-Wesley Professional; 2006)

This book provides excellent coverage of concurrency in Java. The book contains many tips on concurrent programming that are applicable to any language.

Mastering Regular Expressions
Jeffrey E. F. Friedl (3rd edition; O'Reilly Media; 2006)

This is the standard text on regular expressions—a very interesting and useful book. Most of the coverage is understandably devoted to Perl—which probably has more regular expression features than any other tool. In addition to its coverage of regular expressions generally, it has specific chapters devoted to Perl, Java, .NET, and PHP regular expressions. Incidentally, a different kind of regular expression engine was created for Google by Russ Cox—re2—which is well worth reading about. Although specific coverage of Python isn't present in the book, since Python supports a large subset of what Perl provides (plus Python's own ?P extensions), the book is still very useful to Python programmers. Furthermore, an excellent and well-established and much more powerful and more Unicode-friendly Python regular expression library is available from PyPI: regex.

Security in Computing
Charles P. Pfleeger, Shari Lawrence Pfleeger (4th edition; Prentice Hall; 2006)

This book provides interesting, useful, and practical coverage of the broad range of computer security issues. It explains how attacks can be made and how to protect against them. However, I did find it a rather dry read.

C in a Nutshell
Peter Prinz, Tony Crawford (O'Reilly Media; 2005)

This is the best C reference book I've read. It gives comprehensive coverage of the C language and the standard library. This is the book to buy once you've read a tutorial book on C—although very experienced programmers may find that this book is sufficient to learn from in its own right.

Effective C++: 55 Specific Ways to Improve Your Programs and Designs
Scott Meyers (3rd edition; Addison-Wesley Professional; 2005)

This book is essential reading for any C++ programmer. It describes many subtle pitfalls and explains lots of good practices. An additional book that is also essential reading—and which covers C++11 and C++14—is Meyers' Effective Modern C++.

Code Complete: A Practical Handbook of Software Construction
Steve McConnell (2nd edition; Microsoft Press; 2004)

This book shows how to build solid software, going beyond the language specifics into the realms of ideas, principles, and practices. The book is packed with ideas that will make any programmer think more deeply about their programming. The book's examples are mostly in C++, Java, and Visual Basic, but are readily translatable and applicable to other languages.

Linux Programming by Example: The Fundamentals
Arnold Robbins (Prentice Hall; 2004)

A useful and accessible introduction to Linux programming using the Linux system call APIs. The book's examples are in C.

C++ in a Nutshell
Ray Lischner (O'Reilly; 2003)

This useful book provides a solid, compact, and comprehensive reference to the C++ language and its standard libraries (including the C libraries that are part of the C++ standard). Unfortunately it doesn't cover C++11.

Domain-Driven Design: Tackling Complexity in the Heart of Software
Eric Evans (Addison-Wesley Professional; 2003)

A very interesting book on software design, particularly useful for large, multiperson projects. At its heart it is about creating and refining domain models that represent what the system is designed to do, and about creating a ubiquitous language through which all those involved with the system—not just software engineers—can communicate their ideas. The book's examples are in Java.

Rapid Development: Taming Wild Software Schedules
Steve McConnell (Microsoft Press; 1996)

This book takes a strategic—project-oriented—approach rather than a tactical—code-oriented—one, as it explains the software development process and how to manage it. I still have this book and it sticks in my memory because while I was reading it I was working on a software project that made just about every mistake the book covers. (The project was finally killed off a few years after I'd moved on.) The book is evidence-based and still interesting despite its age.

Design Patterns: Elements of Reusable Object-Oriented Software
Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (Addison-Wesley Professional; 1994)

Deservedly one of the most influential programming books of modern times. The design patterns are fascinating and of great practical use in everyday programming. The book's examples are mostly in C++, with some also illustrated using Smalltalk. One consequence of this book's success is that many more design patterns have been discovered since its publication, and some of the patterns it describes have become controversial.