The number of software luminaries who sing the praises of “Structure and Interpretation of Computer Programs” (referred to as SICP) is such a long list that you might think only a crazy person would take issue with it. However, to ignore SICP’s problems and continue to blindly recommend it seems just as crazy.
SICP was the textbook for MIT’s introductory programming class and was a bit of a departure from other into to computer science textbooks at the time. Wikipedia sums it up nicely: “Before SICP, the introductory courses were almost always filled with learning the details of some programming language, while SICP focuses on finding general patterns from specific problems and building software tools that embody each pattern.” Which sounds awesome, but does essentially say that abstract principles will be introduced before the nuts and bolts of a language. If you think about that for a minute, you may see where the problems will be.
When I was training to be a teacher I took a bunch of education courses. I got good grades but when I got into the classroom to actually teach I flailed around just trying to keep the class under control and mostly forgot to apply the principles I had learned. The knowledge was in my head, but it floated, disconnected, from anything in particular. When I learned these ideas I had no teaching experience, and so, nowhere to place these abstract principles.
SICP’s first chapter explains the basic form of Scheme (a Lisp), some basic operators (+, -, *, /, etc), defining/calling a function, different ways a compiler might evaluate code, and conditionals over the course of a few short pages. That’s a bit much to swallow all at once, especially the comparative evaluation stuff but that should be easily sorted out with some examples. Right? Well, that’s not really SICP’s thing. SICP will give you a few trivial examples and then toss you right into the deep end. Then first 2 problems for the reader are pretty easy, but it’s the 3rd that will let you know what yer in for: “Define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers.” Which seems pretty easy until you realize there are no variables. You’ll need to figure out an algorithm that can take 3 numbers and, without any intermediate state storage, return the 2 biggest numbers in such a way that you can sum their squares. I’ll be real honest here, after about 30 min of trying to do this (I have zero functional background so I’m a complete novice here) I gave up and tracked down the answer online. Of course the answer was simple and concise and made me feel like a chump. Which is fine, but not really what I was expecting in the first chapter, let alone the 3rd problem of the entire book.
But that’s what SICP is all about -- challenging problems. The rest of the chapter introduces Newton’s method for square/cube roots and lexical scoping just for fun. Chapter 2 is recursion vs iteration in terms of execution speed, resource usage, and transforming from one to the other. Logarithmic, linear, and exponential growth are dealt with in a few paragraphs and then we’re off to Exponentiation, Greatest Common Divisors, Primality, and implementing Fermat's Little Theorem for probabilistic prime determination. My favorite question from chapter 2 asks the reader to formulate an inductive proof that Fib(n) is the closet integer to ((golden ratio)^n)/5.
Which brings me to another criticism of SICP: It assumes a familiarity with math that most people just don’t have. A first year MIT student would probably be swimming in math classes so the book assumes that knowledge on the readers part. Abstract programming principles can be very difficult to find examples for so I’m sympathetic to the plight of the authors, but when you just go straight at math you’re explaining an abstract thing with another abstract thing.
There’s a certain sort of person who gets excited by complicated abstract but internally consistent logic with no real connection to the concrete. In my experience as a physics teacher, these students do exist but are very rare. Most people need a bit of connection to something tangible in order to have the ideas connect in their brain.
What then is my point about SICP? Simply that its explanations are overly terse and its problems are large steps past what little is explained. In light of those things I have recommendations for those who attempt to work through it.
- If you intend to do every problem, realize that this will take a LONG time and involve a bunch of research.
- Set a time-box for how long you’re going to spend on a problem before you go look up the answer. If you’ve spent enough time trying to solve a problem you will still value the answer enough to remember it. 30 min is a good number. Increase or decrease as your sanity allows.
- If you feel like something hasn’t been explained: You’re probably right. After you find the answer, a close re-reading will reveal a cryptic sentence that you now realize was trying to tell you something. This will infuriate you and is perfectly normal.
- Work through the book with a group. This will hopefully allow you to commiserate about how lost you are and get some help. If there’s someone in there that loves this book and thinks everything is explained perfectly, ignore them. If they subtly imply that you’re stupid for not getting it: Leave the group. You don’t need that static in your life.
- Do not feel bad about not knowing all this math stuff: Remember that this book was written for students who would be surrounded by math at the time they read it.
- Consider learning Lisp before starting this book. The really important concepts in the book come easier if you’re not also learning Lisp at the same time