Like many programmers, I’m always on the lookout for the perfect programming book. Over the years I have tried to enumerate a few key examples, however after reading them all I am still left wanting. However, I recently came across a couple interesting blog posts 1 that motivated me that the only way to find the set of perfect books for programmers was to build them myself.
The process is simple:
- Define the set of topics
- Find the PDFs comprising the aggregate essays for each topic
- Create a table of contents, forward, and write or steal a summary of each essay
- Merge everything together
- Go to Lulu.com and print a book 2
- Read the books
- Become a better programmer (i.e. profit)
YOU, and NO ONE ELSE, is responsible for your career. — Uncle Bob Martin
After thinking about the possible topics that would be beneficial to my own enrichment (and to the programmer in general), I hit on the following seven:
Things that every programmer should know and read about; taken mostly from the list compiled by Michael Feathers with some of my own additions.
The Lambda Papers
Including the original Lambda Papers and relevant essays pertaining to them and their topics.
Topics concerning functional programming in general including, but not limited to: state, immutability, lambda calculus, purity, recursion, pattern matching, laziness, type systems, closure, anonymous functions, and currying.
One way to learn more about developing new programming languages is to learn how other programming languages were created. This book would be similar to the previous two books except with a slant toward the more practical aspects of language development.
While I am learning more and more the virtues of functional programming, I still think that object-oriented programming has just as an important role as ever in software design and development.
Software Development Management
While my own brief foray into software development manager can only be described as a failure, I believe that the right person implementing the right management techniques can be as valuable as the greatest programmer that you’ve ever met.
Operating Systems Development
From web-based, to monolithic, to exo-kernel, to micro-kernels, there is a lot to be learned from the field of operating system development and their relationships to the underlying hardware; as long as I do not constrain myself to the Von Neumann architechture.
Interviews and Anecdotes
What better way to become a better software developer and designer than to read about the art from the masters.
And that is it. I think that after crunching through the seven books outlined above, I should, at least minimally, be smarter than I was this time last year. I’m always looking for suggestions and comments about my outline above. I do not want these books to be my vision of the best, but instead I want them to be the best available. In addition, I will likely discover new essays, code snippets, and interviews after books are created, so I will likely create an 8th or even 9th book to cover those.
To end this post, I present the table of contents and summary section 3 to Book 0: Core:
THE ORIGINS OF PATTERN THEORY THE FUTURE OF THE THEORY, AND THE GENERATION OF A LIVING WORLD – Christopher Alexander
- On the Criteria to Be Used in Decomposing Systems Into Modules – David Parnas
- A Note On Distributed Computing – Jim Waldo, Geoff Wyant, Ann Wollrath, Sam Kendall
- The Next 700 Programming Languages – P. J. Landin
- Can Programming Be Liberated from the von Neumann Style? – John Backus
- Reflections on Trusting Trust – Ken Thompson
- Lisp: Good News, Bad News, How to Win Big – Richard Gabriel
- An Experimental Evaluation of the Assumption of Independence in Multiversion Programming – John Knight and Nancy Leveson
- Arguments and Results – James Noble
- A Laboratory For Teaching Object-Oriented Thinking – Kent Beck, Ward Cunningham
- Programming as an Experience: the inspiration for Self – David Ungar, Randall B. Smith
- Equal Rights for Functional Objects or, The More Things Change, The More They Are the Same – Henry G. Baker
- The Universal Design Pattern – Steve Yegge
- A Universal Modular Actor Formalism for Artificial Intelligence – Carl Hewitt, Peter Bishop, Richard Steige
- The Humble Programmer – Edsger W. Dijkstra
- Notes on Programming in C – Robert Pike
- Go To Statement Considered Harmful – Edsger W. Dijkstra
- Callbacks in C++ Using Template Functors – Rich Hickey
- What Every Computer Scientist Should Know About Floating-Point Arithmetic – David Goldberg
- Duff’s Device – Tom Duff
- MATREX Data Collection and Analysis: Linking Simulation Results to Military Analyst Requirements – Michael Fogus, Dave Prochnow, Kuan Penn, Howard Borum
On the Criteria to Be Used in Decomposing Systems Into Modules – Parnas
This is a very old paper, but it is more than a classic. In in it, Parnas introduces a forerunner to the Single Responsibility Principle. He introduces the idea that we should use modularity to hide design decisions – things which could change. People still don’t consider this as often as they should.
Another thing I really like in the paper is his comment on the KWIC system which he used as an example. He mentioned that it would take a good programmer a week or two to code. Today, it would take practically no time at all. Thumbs up for improved skills and better tools. We have made progress.
A Note On Distributed Computing – Waldo, Wyant, Wollrath, Kendall
Abstraction is great but it can only go so far. In this paper, the authors lay to rest what was once a pervasive myth – that we could design a distributed system and make distribution transparent. Ever wonder why you had to implement specific interfaces to do remoting in Java? This is why.
In the aftermath it might seem hard to believe that people thought this was possible. I think we can we partially thank this paper for that.
The Next 700 Programming Languages – Landin
Most of us have spent a lot of time working in traditional programming languages, but functional programming languages are slowly seeing an uptick and many OO languages are gaining functional features. This paper (which reads like a tutorial) makes an argument for an expression-oriented style of programming. It also lays the foundation for lazy evaluation.
One of the other neat things about this paper, from a historical point of view, is that there is a discussion section at the end in which there a number of questions and comments about whether making indentation significant in a language is a good idea. I was thrown to see people asking whether or not this would be a problem for functions which span over several pages(!).
Can Programming Be Liberated from the von Neumann Style? – Backus
John Backus is known for a number of achievements in computer science. He received the ACM Turing Award for his work on Fortran. This paper, which he presented at the award ceremony was rather shocking at the time because it said, in essence, “we got it wrong.” Backus took the opportunity to make a plea for pure functional programming. His arguments were convincing and they helped to set a research agenda which is just now starting to make some waves in the mainstream.
Reflections on Trusting Trust – Thompson
I once heard that when this paper was presented, people in attendance rushed back to de-compile their C compilers and look for, er, problems. This paper unveiled a hard problem at the heart of computer security. If you’ve spent any time at all thinking about security, you need to read it.
Lisp: Good News, Bad News, How to Win Big – Gabriel
This paper is a bit atypical in this list. It’s aimed at the Lisp community and it comes off as a bit of a lament. But, hidden deep within it is the Gabriel’s description of the ‘Worse is Better’ philosophy – an idea with profound implications for the acceptance and spread of technology.
An Experimental Evaluation of the Assumption of Independence in Multiversion Programming – John Knight and Nancy Leveson
Behind this dry title lies something very interesting. I first heard about this paper from Ralph Johnson in a newsgroup discussion about program correctness. It turns out that one of the avenues that engineers in other disciplines take to make their products stronger – redundancy – doesn’t really work in software. Multi-version programming was the idea that you could decrease faults in critical systems by handing the spec to several teams, having them develop the software independently, and then having the systems run in parallel. A monitoring process verifies their results and if there is any discrepancy it picks the most common result. Sounds like it should work, right? Well..
Arguments and Results – Noble
I think that all of the other papers in this list are rather well known in some circles. This one isn’t, or if it is, I just haven’t found that circle yet. What I like about this paper is that it takes something which we deal with every day – the set of arguments and results of functions – and it works them through a series of variations which just don’t occur to many people. The fact is, every function that you work with has a number of possible directions if could evolve in. Not all of them are appropriate, but if you know the possible directions, you’re richer for it.
A Laboratory For Teaching Object-Oriented Thinking – Beck, Cunningham
There are an incredible number of papers about there about object orientation. The thing which makes this one great is its directness. OO went through a number of stages. It was once fresh and novel, then it was ornate, and then it became matter-of-fact. This paper hits upon key ideas which many people don’t talk about much any more: anthropomorphism and dropping the top/down perspective. It also shows you how you can design with index cards. It may not sound cool but it is incredibly effective.
Programming as an Experience: the inspiration for Self – Ungar, Smith
How many people know about the Self Project? Not enough in my opinion. Self was an attempt to take two ideas in computing and push them as far as humanly possible. The first was minimalism: the Self programming language was thoroughly in the Lisp and Smalltalk vein – everything was defined in terms of the smallest number of primitives possible. The other idea was direct manipulation – the idea that the object metaphor could be pushed all the way in the user interface – the programmer and user sit with a mouse in a sea of directly clickable objects and use them for everything. If they could’ve gotten away with dropping the keyboard, I think they would’ve.
Equal Rights for Functional Objects or, The More Things Change, The More They Are the Same – Baker
Baker describes the egal predicate which is used to recursively compare functionally persistent objects.
The Universal Design Pattern – Yegge
Yegge describes the Universal Design Pattern which, in a nutshell, mirrors the classical Properties Design Pattern with an added pointer to the parent object. Yegge describes methods of providing an inheritance mechanism similar to prototypal inheritance.
A Universal Modular Actor Formalism for Artificial Intelligence – Hewitt
With the recent emergence of the Erlang programming language’s Actor-based event model, the ideas created by Hewitt, et al. become increasingly important. The Actor model has been the guiding motivation for many important programming languages, including, but not limited to, Scheme and the aforementioned Erlang.
The Humble Programmer – Edsger W. Dijkstra
In a nutshell, most of programming design is done in an attempt to compensate for our lack of intelligence. Those programmers who are at the bottom of the competency pyramid refuse to recognize this fact are doomed to remain subpar. The way to enlightenment and improvement is by recognizing our limitations and proceeding with a level of humility.
Notes on Programming in C – Pike
Pike’s Notes on Programming in C provides approaches to design and implementation applicable to every project, be they C or not.
Go To Statement Considered Harmful – Dijkstra
The classic text denouncing the goto construct is largely moot today, but it is an essential read for the thoughts on structured programming by a true master.
Callbacks in C++ Using Template Functors – Rich Hickey
The inclusion of this paper is questionable considering the groundbreaking essays surrounding it. However, it is an interesting (and rare) read from a thoughtful programmer currently making waves.
What Every Computer Scientist Should Know About Floating-Point Arithmetic – Goldberg
This essay would not be included if the number of programs fraught with rounding errors was less than 10,000 per year. Programmers still do not understand floating point arithmetic (myself included; which I hope this will remedy).
Duff’s Device – Duff
Duff’s Device is often held up as an example of the quintessential programming pearl. Combining a concise and clear implementation of a common programming problem with a deep understanding of the programming language (C), Duff’s Device still has a lot to teach us.
MATREX Data Collection and Analysis: Linking Simulation Results to Military Analyst Requirements – Fogus
My goal in this series is personal enrichment. Therefore, I would like to include one of my own essays as a way to offer a stark contrast between my own output and those of the true visionaries. My goal is not to offer my own essay as standing firm with those that come before it, but instead as an humbling afterward. Through the recognition of my shortcomings I hope to become a smarter designer and developer of software systems.
The first was by Michael Feathers entitled 10 Papers Every Programmer Should Read (At Least Twice)) and the second by Emmet Connolly entitled Instapaper (analogue edition). ↩
I have no idea what the copyright implications of this are, so I will be priting out only my own private copy and not making them available publically; but with a little bit of work you too can do the same. ↩