I started with a new team in the middle of this year and as I get to know the other members of the team and share our skills and experiences, the books that each of us has found influential has come up. This has given me the opportunity to reflect a bit on which ones I still find worthy of suggesting that others read. Over my career, and as my family has grown, I have become acutely aware of the value of my free time and that of my co-workers. With that in mind, I’m recommending and sharing a lot less than I used to, and since a coworker (Aaron Feng) recently made a point of thanking me for my recommendations I thought I’d journal what I’ve been pushing at this new team.
My current bookshelf contains the books it does after several rounds of being distilled over the past ten years or so. Even so, there is a mix of titles that have been there for years as well as some recent acquisitions that I suspect will have longevity.
Higher-Order Perl: Transforming Programs with Programs, by Mark Jason Dominus
If you program in Java, C#, Python, Ruby or another imperative, stateful language, this is perhaps the best book you can pick up to learn several core fundamentals of functional programming. It is a great introduction to performing functional programming in an imperative, stateful language. Mark goes through the process of showing you how to implement things like Haskell’s infinite sequences, the use of higher order functions, and several other fundamental tenants of functional programming.
I lent my copy to Aaron and it was he that started to tell me where in the book he is seeing some of the techniques that I use on a regular basis. Mark is a great developer and more than just functional programming comes across in the book, a lot of his skill and clarity of thought does as well.
I feel very sorry for any of you that can not get over the fact that this book’s code examples are in Perl.
I picked up PAIP along with ANSI Common Lisp (by Paul Graham) with the intention of learning Common Lisp. I wasn’t prepared for what was in PAIP when I first struggled through the book. I started with an expectation of learning about AI, with little expectation of picking up practical techniques that I’d be able to apply in my day job developing web applications. What I got out of the book was much more than I anticipated. I’ve gone back to it multiple times and it sits on the top shelf in my book case. PAIP was my first introduction to how deep a subject search really was, it jump started my knowledge about lisp, continuations, functional programming, declarative programming, domain specific languages and teased me with CLOS. Each of these topics is deep enough to warrant its own book, Dr. Norvig introduces each, often including implementations, in a single book.
After being introduced to and exploring common lisp from PAIP and ANSI Common Lisp, I had started to use, but not completely understand Lisp macros. I was only beginning to understand the implementation of, and recognize the appropriate application of the
once-only macros. I had a fuzzy conception of hygiene with respect to what it meant for macros. JRM’s syntax primer introduces R5RS’s alternate macro system:
syntax-rules is based on pattern matching and recursive expansions, and it was automatically hygienic. This seemed like magic and seemed to eliminate many of the hygiene problems that you encounter with the traditional Lisp style macros. It forced me to think about code generation in a completely different light. The primer is fairly short for the topic it introduces and the material helped me with some fundamental understanding. The greatest influence this had was to introduce to me new ways to develop and maintain DSLs and code generators.
Joe Armstrong said that when Ericson was creating Erlang, they decided their primary concern was robustness, that to have robustness you needed at least two computers and that most of the rest of the features in Erlang flowed forth from there. To me Erlang has come to embody what robustness really means: a platform that is capable of achieving nine 9’s, that concentrates on fail-fast or crash early so that you have more hope of recovery, supervision trees of processes so you know when things go awry and can handle them from a safe distance, the ability to update code live in a running system so that you never have to bring it down. Erlang is the only platform and language that I’ve encountered that has internalized these principles into its core.
The book increased my exposure to pattern matching, introduced me to list comprehensions and message passing concurrency (gave me the name for the actors model of concurrency).
The 22 Immutable Laws of Marketing: Violate Them at Your Own Risk!, and The 22 Immutable Laws of Branding, by Al Reis
Rob Di Marco recommended this to me when I had the privilege of working directly with him. It was something that was outside my core area of expertise and interest (technology, software development in specific). I keep seeing the principles they detail show up all around me – they gave me another model for observing interactions between people, the purpose of blogs, twitter, and how you can use all of communication and points of contact to help shape how people perceive you. They made me realize, and gave me a starting guide, for how to market and brand myself. Mostly as a developer and technologist, but also in a few other ways. Given that IT folks tend to be introverted and not understand the power that how others perceive them has over their interactions, this is something I try to repeatedly recommend to those that I work with.
Applied Cryptography: Protocols, Algorithms, and Source Code in C, Second Edition, by Bruce Schneier
I read Applied Cryptography from cover to cover as fast as I could manage to. At the time I read it there was a lot that was new to me: the historic context, some of the information theory, the idea that there were known best ways to attack the best known algorithms that reduced the effectiveness but did not outright invalidate the approaches, and it drove home the idea that security can not be absolute, that it is a balance between usability and restrictiveness. This helped hone my sense of information leakage in my own development, from what is stored in files and databases, to log statements to what is exposed thorough error messages and stack traces, where user input comes from and goes to.
Design Patterns: Elements of Reusable Object-Oriented Software, by the Gang of Four (Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides)
The gang of four book was at first a set of design guidelines, over the years its importance as a design guide has waned and, for me, it has shifted more towards being important because it establishes a shared vocabulary with other developers. Having the vocabulary allows us to describe the systems and frameworks we’re using and creating in a way that increases understanding and minimizes misconceptions.
Refactoring: Improving the Design of Existing Code, by Martin Fowler
This emphasized the importance of unit testing in the ability to effectively maintain and improve an existing codebase. It introduced me to the ideas of test driven development along with the pragmatic programmer.
TCP/IP Illustrated, Volume 1: The Protocols, and UNIX Network Programming: Networking APIs: Sockets and XTI; Volume 1 by Richard Stevens
Having read these books has served my career well over the years. The introduction to the protocols, and the networking APIs, has been invaluable. The single most important thing I took away from this book was how I/O Multiplexing (select/poll, non-blocking IO) worked and how efficient it could be.
Programming Perl (3rd Edition), by Larry Wall, Tom Christiansen, and Jon Orwant
Perl was the first dynamic language I learned (having programmed only in compiled languages before it). I think the camel book was my first O’Reilly title – many, many more followed. O’Reilly as a publisher deserves a lot of credit for helping to bootstrap my programming career. Programming Perl showed me that a language, its creators and practitioners, and especially its community could have character. It emphasized that programming should be enjoyable and fun. “Easy things should be easy and hard things should be possible” is a great slogan for a language – a language that had a slogan!
Algorithms in C++, Parts 1-4: Fundamentals, Data Structure, Sorting, Searching (3rd Edition) (Pts. 1-4), by Robert Sedgewick
Sedgewick provided me with my first introduction to ‘Big Oh’ notation. His examples displayed an enormous amount of thrift, some of the best examples I’ve seen of using the minimum necessary to implement the chosen algorithm. This was not minimalism to the point of terseness, it exemplified that with a clear understanding of the problem, the choice of an algorithm that closely fit the problem, implementations should be clear and uncluttered. The aesthetic of using minimal language features so as to be as clear as possible was a clear influence on me.
I was first introduced to fuzzy string matching through this book, which turned out to be an interesting problem domain. I spent about eight years working for a data integration company applying many of the things I first discovered from these algorithms books.
The Pragmatic Programmer: From Journeyman to Master, by Andrew Hunt and David Thomas
Continual improvement. Keep questioning and seeking better processes, techniques, solutions. Learning a new programming language on a regular basis was the single most memorable part of that book for me. That particular advice has worked particularly well for me. I believe that each programming language was created to address a core issue or difficulty that its creator was experiencing. The language is a manifestation of their understanding of the issue and a simplified design that makes that issue easier to contend with. Some address multiple issues. My impression of C is that it made for more structured interaction with the hardware’s basic features (at a time when there was little). C++ improved the expressiveness of C, introducing OO without moving too far away from the machine. Java eliminated memory management and pointer manipulation mistakes that programmers were so often tripped up by in C and C++ applications, simplified platform dependency issues, and smoothed over some of the complexity of the OO features in C++. Perl worked to integrate other tools, most often that produced or consumed text, it was an integration toolbox and grew from there towards a powerful and terse high level language. Lisp removed all barriers to abstraction, it eliminated the sacred parts of the language and put all their power into the hands of the developer: to do their best, or their worst.
The Practice of Programming, by Brian Khernagin and Rob Pike
They tell you to continue to hone your skills, develop your craft, continually improve. Develop your vocabulary and ability to name things clearly and concisely as it very much matters in the clarity of your software. Learn your tools. This is one of the books I have to thank for my never-ending stream of reading and continued exploration of this field.
Surely You’re Joking, Mr. Feynman! (Adventures of a Curious Character), Richard P. Feynman
Intellectual curiosity. Looking outside the box. There is another way to view things. Trust your intuition and be tenacious – if there are only 2 possibilities and the evidence is inconclusive, discover new evidence, don’t just discard the original axioms – this attitude has been a huge help in debugging. In some ways it comes down to having faith in yourself. I hope my children choose to read and are inspired by Feynman’s writing.
Though I enjoyed both Snow Crash and The Diamond Age, I was more inspired by his vision of a young lady’s illustrated primer. You see the ideas he was exploring in the primer continuing to manifest themselves over time. How the Internet is permeating all our devices and experiences, the collaborative nature of how Wikipedia and other crowd sourced assets are being created, Amazon’s Kindle ebook reader (with on-line access to new content) and discritized task sites like the Mechanical Turk. I want to be able to gift my own children with their own primers.
Penn and Teller’s How to Play with Your Food, Penn Jillette and Teller
Thinking outside the box. Looking at things for what they are, not just for what they seem. Seeing alternate, unexpected, uses for common things. In showing how effectively you can deceive your senses, the book helped give me a good sense of skepticism – not taking something at face value if it didn’t seem right (I tie this to debugging believe it or not).
Other Lists of Influential Books
Since the time I wrote this post I’ve been contacted by others (one at this time) with their lists. I’ll update this periodically with those where I find new books:
These are books that have had staying power in my bookshelf. I’d love to hear your own thoughts if you do decide to pick any of these up, or even if you’ve already been through their pages. I always ask people what books they’ve found influential as a standard question when I interview developers. What do you recommend?
Special thanks to Jonathan Tran, Aaron Feng, Rob Di Marco and others who have lent and recommended books to me over the years. A second thanks to both Jonathan and Aaron for reading drafts of this post.