Jake Scruggs

writes ruby/wears crazy shirts

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


Renzo said...

… it was probably written for the other 50% :)

As you can see if you look around, there is a good 50% of people who deeply hate SICP for some of the reasons that you mentioned. I'm deeply in love with SICP but I have to admit that I knew about its existence after I spent sometime learning Clojure. It was my interest in Clojure that guided me through the history of functional programming, down to some of the suggested papers and books, SICP included. An example. When I landed on the SICP I knew already about the "let" form but never realized it was just syntactic sugar for an anonymous function declared and invoked in-place. SICP for me was full of many other of these ah-ah moments (and I'm still slowly reading chapter 3). Maybe you should go down the route of Koans and tutorials for your favourite FP language first and revisit SICP after that. As of the math background, I agree that is not the most entertaining subject, although in my case when I discovered SICP I was already on a path of rediscovering (after my university days) math and SICP forced me even more down that path. Hope you can give SICP a second try at some point in the future. The book is clearly a gold mine of every concept in computer science that will, sooner or later, come cross your path as a developer.

Jake Scruggs said...

I probably should have said somewhere in my post that I'm enjoying reading the book despite my criticisms. As a teacher, I'm annoyed by some things but as a programmer I'm delighted to have my brain bent in a new way.

Anonymous said...

Jake, another physicist turned programmer here. You must've learned E&M from a different book than I did. I had a prof praise it because "not a word was wasted." As a student I hated that because I was on the hook for the exercises. When I read SICP about 10 years ago, I loved it (and I should re-read it) but then again I didn't feel the need to work the exercises.

Anonymous said...

I feel better now :)
I tried to read it a few years back and ran exactly into the issues you describe. In the back of my mind there was the thought that I sucked because I couldn't read the whole thing.
I will try it again with these caveats in mind.

nobody said...

Scheme was the first programming language that I was ever taught - in an introductory CS course that was heavily influenced by SICP. I may have vaguely known that the book existed, but I didn't go back and read it until probably five years ago. I think it's a little intense, especially when I reminisce on my days as a slacking college freshman.

I honestly feel like that learning path set me up for success as a programmer. I was introduced to fundamental concepts like recursion in the first few weeks of my CS education. I've met younger folks who graduated (something I never did) with 4-year degrees in CS (and subsequently managed to get hired as programmers) who had no grasp of that concept. I know that may sound hard to believe, but I keep meeting these people.

There's this idea floating around in a lot of communities that OO is the bestest style of programming, like, ever, bro. I think that's really dangerous - a whole lot of really bright folks believe that wholeheartedly. I think they are kind of brainwashed, and the net effect is that their intellectual curiosity is stifled. I love programming because I can create anything I can imagine while learning every day and getting to solve problems. All that, and I get paid to do it.

I guess I should try to make a point here...thanks for posting some good honest criticisms of the book. And good for you for keeping on it even so. I think the world needs more evangelists for learning new and different things - it will only make us all better.

Anonymous said...

I agree that SICP isn't a good book for programming beginners. It's more for intermediate programmers. Reading the book, you go from the stage where you think of code as a way tell a computer what to do, to thinking of code as a way to actually express and refine ideas.

About the problems, I think you might be missing the point. There's no need to solve all the problems in the book as you work through it. In fact, in my opinion that's precisely the wrong way to read it. Some examples are indeed very advanced. This is intentional - the authors want you to appreciate the power of abstraction that lisp offers. Unfortunately it's not always possible - or justifiable - to do this with worked examples or simple problems. It's entirely acceptable to look up the answers online or ask someone who's done them already. In fact, I would definitely encourage doing this, just like you mention.