Books that can (eventually) make you a better programmer


Abstract

I love reading and I love reading technical books as well. I did read manyof the but the following ones are the ones that I value most and that I think changed the way I program and think about software. You will maybe have others or just not being in agreement with me but this is my list. Enjoy!

I had the chance to read many books about programming, and software engineering and design since I started the university 15 years ago but, as often happens, I consider only an handful of those books to be good and worth of being defined formative.

The following list has been refined many times in the years and it was created out of suggestions that I gave people asking me how to grow up professionally or, in more general term, how to become better programmers.

Furthermore, the following list is very personal and I believe that not everyone would agree with my choices but, as it always happens in life, I believe that it is both a matter of personal taste and a matter of what you had to face in life. Let's say that the following list fits my history and personal taste.

Programming Pearls by Jon Bentley — This is quite an old book. The first edition dates back to 1986. It is essentially a design book focused on "designing in the small": how to write efficient algorithms, how to think about problems, how to trade space for speed and so on. It is divided in "columns" since it was a collection of columns previously published on the "Communications of the ACM" journal. It is a strictly technical book with many real life experiments and it appears clear, reading it, that the it is written out of the personal experience of the author himself. Sometimes a critique is moved to this book: now that machines are faster and with memory is inexpensive, this book is no more as valuable as it used to be. From my personal experience that is false for essentially two reasons. The first one is that if you change memory with cache, you are exactly at the same point where we used to be 20 years ago and there is no need to waste machine cycles for nothing. The second one is that, depending what you do, 24GB of RAM can be a little amount, for instance when you are trying to cluster more than 30 GB of raw data. At that point, learning how to think about data structures layout is an essential need to complete your job.

The Practice of Programming by Brian W. Kernighan and Rob Pike — Practical software engineering and development with examples in 5 different languages compressed in less than 300 pages. 300 dense and enjoyable pages. This is another book written out of experience by two of the inventors of Unix, the C programming language, AWK, dot, etc. It covers the practical things: how to debug, how to test, how to write portable code, how to profile code, how to comment the code in order to be effective and not annoying, how the expressiveness of programming languages affects program efficiency (i.e., trading programmers time for machine time) and everything ends with a description of how to, essentially, write a virtual machine/interpreter. The code used as example is beautiful: essential to the extreme and using a beautiful style. After reading this book, you are definitely going to be a better programmer.

The Mythical Man Month and Other Essays on Software Engineering by Frederick P. Brooks Jr. — This book is immortal. It was written in 1975, which means that this book is older than I am. When you read it - if develop software professionally - you can immediately notice that the world of software engineering did not change that much after all in all this time. And actually, this book tells you why, after so many years, it did not change a lot: while software tools evolved a lot and we how have higher level programming languages, debuggers capable of giving precise insights of what is going on at run-time and profilers able to tell you precisely where your program is spending time; unfortunately, the humans developing software did not evolve as much and the problem space did not change that much. Software engineering is essentially a brain intensive activity and the human brain did not evolve in such a short time. Even if tools did evolve a lot, people are the same and all the human problems, such as communication, work split among design, coding and testing did not change. No matter how better your debugger is now with respect to then, testing and integration (which is testing in a more painful form) will always take more or less the 50% of the development process, coding your algorithms and data structures only 1/6 of the project time and the rest is design. If you worked enough in software production, you know that this is true now as it was when the author was involved in the OS/360 project back in the 60s. Another important take out from the book: it is the data shaping the algorithms and not the other way around.

Code: The Hidden Language of Computer Hardware and Software by Charles Petzold — This is one of my favourite books ever. This is the way I would have had Computer Architecture to be taught to me. It starts from information representation and numbers (using lamps, fingers and the braille system) and it arrives to programming languages implementation and their mapping to processor instructions. All of that, passing through how information is stored in bits, how register and circuits work, how to build an arithmetic adder with lamps and switches and how those circuits map to the building blocks of a processor. Computer Architectures explained bottom-up starting from the problem they were invented to address and not from the solution itself, as all the other Computer Architecture books are structured. Reading this book, my understanding of information representation and how that match in circuits improved a lot. Knowing what is really under the hood helps you understanding how to bend the high level tools in order to make them do exactly what you want them to do. Also if you already know a lot about Computer Architectures, this is definitely a book that will teach you a lot and that will change the way you look at a computer forever. While the magic of how those infernal machines work will disappear, it will disappear for good. Really.

The C Programming Language by Brian W. Kernighan and Dennis Ritchie — This book, written in 1975, made its way into this list not because the C programming language is a programming language that you need to know as a software engineer, but because it is the most brilliant example of how you should write technical documentation and because it contains some of the most beautiful, and elegant, code examples that I ever had the fortune to read in my entire life. In around 250 pages, the two authors describe the language syntax, its standard library and tell you how to use the language to get the job done. An hymn to brevity and clarity. I was never able to produce documentation of such beauty, brevity and clarity as the two authors were able to. I did try my best and I failed. I probably continue reading this book trying to learn how to do the same moved by envy alone but this is probably one of the few cases in which envy is a positive thing because it make you read something good. Such a brevity, elegance and clarity is expressed in the code examples themselves. I do not want to try to explain why but I will leave it to an example. The following function takes in input a day, a month and a year and tells you which day of the year is that (e.g., the February 21th, 1978 is the 52nd day of the year 1978):

static char daytab[2][13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

int day_of_year(int year, int month, int day) {
    int i, leap;
    leap = year%4 == 0 && year%100 != 0 || year%400 == 0;
    for (i = 1; i < month; i++)
       day += daytab[leap][i];
    return day;
}

Programming Language Pragmatics by Michael L. Scott — You cannot name yourself a software engineer, or just a programmer, if you do not have a natural love and curiosity around programming languages. Programming languages are the abstraction that we created, as software engineers, in order to command machines and telling them what to do. This book is my favourite one on the subject. It describes, or just able to mention, almost 100 programming languages telling why they are the way they are, what problem classes they are meant to solve and how they address them. The author also finds the time to talk about parsing, abstract syntax trees, virtual machines, code optimization and generation, and all the technical details behind a programming language and a compiler. Honestly speaking, programming languages and compilers are probably the best thing you can find in a computer system, essentially because the people who implemented them, implemented them for themselves: they were the very first customers of those languages and then they had to be as less painful as possible and the customer of those programs was very well know and all the requirements were very clear.

How to Lie with Statistics by Darrell Huff — This is the only book of the list that is not about programming. It is not even a book about statistics. It is a book that teaches you what the right questions to ask are when someone presents you some data. And, if you develop software professionally, you have someone coming to you saying: "we (you!) need to implement this feature because our market research tells us this". Good, let's start asking the right questions: how was that market research done? What is the sample size? What was actually asked? Is that a mean or a media? How much is the standard deviation? You probably got it now. Moreover, learning to ask all those questions is actually learning to think out of the box and developing a critical mind especially towards your own job as well.

I believe that the above list will definitely change with time and it will evolve as I do. It will more probably grow more than shrink or a book could be eventually replaced by a newer, at least for me, one.

Some important books are not present in the list (e.g., The Art of Computer Programming by Donald Knuth) not because I do not believe they are not good. Only because I did not read them at all or because I did not read them properly yet. Just as an example, the books above have been read at least twice from cover to cover and some of their chapters were read more than twice because I needed to or just because I just enjoyed reading them again.

If you have some good book to suggest, feel free to write me and telling me about them. Please, do write why I should read them and not just because it is an "awesome" book.