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.
Amazon requires that I state: “As an Amazon Associate I earn from
(In practice the earnings are practically nothing and seem to get less every time they change their terms, which is often.) Note also that there may be newer editions of some of these books.
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 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.
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.
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.
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.
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.
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.
Each recipe is small, self-contained, and well explained. And here and there the author has injected tiny sparks of leavening humour. Recommended.
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.
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
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.
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
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.
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.)
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.
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.
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.
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
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.
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.
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.
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.
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.
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.
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.
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.)
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.)
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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.)
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).
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.
This book provides excellent coverage of concurrency in Java. The book contains many tips on concurrent programming that are applicable to any language.
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
Although specific coverage of Python isn't present in the book,
since Python supports a large subset of what Perl provides (plus
?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.
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.
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.
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++.
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.
A useful and accessible introduction to Linux programming using the Linux system call APIs. The book's examples are in C.
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.
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.
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.
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.
Your Privacy • Copyright © 2006 Qtrac Ltd. All Rights Reserved.