Lets read: Structure and Interpretation of Computer Programs
This is the first entry in the Let’s Read SICP series.
index | next »
I’ve always wanted to read Structure and Interpretation of Computer Programs. It’s kind of a magical looking book, with the wizard on the front pondering his orb, and the flash of lambda frightening the student next to the table with the dragon’s foot.
It has a reputation as one of the best programming books of all time. I’m intrigued that it uses Scheme to teach its lessons.1
That said, I don’t want to read about it in SICP.
So I pulled down off the shelf the Second Edition copy I bought last year and haven’t even opened yet, and decided to give it a go.
The time is now. The moment is here. And you have chosen to go on this journey with me? Very well. Take my hand. Grab a jacket just in case, you can tie it around your waist.
I read all the front matter this morning, the table of contents, the forward, preface to the second edition, preface to the first edition.
There are five chapters of about 120 pages each. If I work diligently at it and cover a mere 20 pages per day, I should be able to cover a chapter a week and complete the book in five weeks. Even if the exercises are especially challenging, I expect I’ll be able to manage them and 20 pages of reading. (Note to future self: this is where you can come back and laugh at my hubris when this turns out to be far more challenging than I anticipated.)
Here are a few quotes that I particularly enjoyed.
Our traffic with the subject matter of this book involves us with three foci of phenomena: the human mind, collections of computer programs, and the computer.
These are indeed the three foci in fact of all human endeavors: the human mind conceives of an idea, a thought, a feeling, an emotion. Then one creates some form of mental model or represention of it. In this case the computer program. And then that model is applied to some medium, some hardware. I think that is how all art is created.
More than anything else, the uncovering and mastery of powerful organizational techniques accelerates our ability to create large, significant programs.
I find this to be true. When things (concepts, items, etc.) are organized and tidied up, they are more accessible and easier to reason about, and your system becomes less complex. On the surface at least. And reducing complexity is of course the most worthwhile pursuit.
First, we want to establish the idea that a computer language is not just a way of getting a computer to perform operations but rather that it is a novel formal medium for expressing ideas about methodology. Thus, programs must be written for people to read, and only incidentally for machines to execute. Second, we believe that the essential material to be addressed by a subject at this level is not the syntax of particular programming-language constructs, nor clever algorithms for computing particular functions efficiently, nor even the mathematical analysis of algorithms and the foundations of computing, but rather the techniques used to control the intellectual complexity of large software systems.
I love this. Let this be the thesis of the book, the focus of the content, and I will love this text.
Two very important points here.
First, that programs are meant to be read by humans and only incidentally run by computers is a truth that intellectually I know, but of which in practice I often have to remind myself. For example, during code reviews I am frequently tempted to suggest a more terse expression because, I suppose, brevity suggests cleverness and who doesn’t want to feel clever. But brevity is also often less legible. And common, shared language is always more widely understood than specialized jargon.3
Second, again with managing complexity. This is a soapbox for me. Almost all human endeavors are attempts at managing complexity. Learning syntax is the work of the novice. Learning to build large programs and structures will keeping complexity at a minimum is the work of the architect, the engineer.
These skills are by no means unique to computer programming. The techniques we teach and draw upon are common to all of engineering design. We control complexity by building abstractions that hide details when appropriate. We control complexity by establishing conventional interfaces that enable us to construct systems by combining standard well-understood pieces in a “mix and match” way. We control complexity by establishing new languages for describing a design, each of which emphasizes particular aspects of the design and deemphasizes others.
Two things here.
First, again with controlling complexity. I won’t say any more about it here other than that I continue to agree with its importance.
Second, it is interesting to point out that the author’s instruction draws from the well of “all engineering design.” I feel as though it’s kind of popular right now to argue about whether we (software engineers) are “real” engineers or not.4
Underlying our approach to this subject is our conviction that “computer science” is not a science and that its significance has little to do with computers. The computer revolution is a revolution in the way we think and in the way we express what we think. The essence of this change is the emergence of what might best be called procedural epistemology–the study of the structure of knowledge from an imperative point of view, as opposed to the more declarative point of view taken by classical mathematical subjects. Mathematics provides a framework for dealing with notions of “what is.” Computation provides a framework for dealing precisely with notions of “how to.”
This starts strong and goes in a curious direction for me.
I’ve heard the introductory sentence said before. “Computer science has little to do with science, or computers.” I believe it has much more to do with (sorry to feed a fed horse) organizing complexity so that we can express our thoughts and describe our systems as correctly as possible. I also think this circles back to the three foci: training our human brains to create useful models that we can represent in some kind of physical form.
The curious ending is distinguishing procedural programming (“How to”) from declarative mathematics (“What is”). Which I suppose is entirely true applied at this level. But I’m used to seeing this distinction made internally, within the world of programming, to distinguish procedural object-oriented programming (“How to”) from declarative functional programming (“What is”). Although I suppose the distinction might be the same given that the FP fundamentalists want programming to be all mathematical functions and lambda calculus anyway.
In conclusion, the introduction to this text was flowery and inspiring, and I am excited to continue on to chapter one and take the first bites out of this big meal.