I went through section 1.3 pretty quickly, as I’ve read this in the past and am already familiar with the main ideas. Still, SICP was my introduction to functional programming, and I still remember seeing the examples in this section for the first time and being amazed at the power of first-class procedures.
One problem that took me a while was 1.41, where you need to define a procedure that takes a procedure as an argument, and returns a procedure that applies the original procedure twice. Writing the definition was easy, but understanding what happens when you compose this function multiple times stumped me for a while.
Here’s the definition for double:
(define (double f) (lambda (x) (f (f x))))
Applying double to inc (which increments a number by 1) causes the resulting procedure to increment a number twice, as expected:
((double inc) 5) ; 7
However, what does this do?
(((double (double double)) inc) 5)
Initially, I thought it would evaluate to 13, because the first (double double) would be a procedure that increased a number by 4. Then, the outer double would apply this twice, resulting in a total increase of 8. However, when you run this, it evaluates to 21! The explanation for this can be found at my solution at https://github.com/edtan/sicp/blob/master/1.3/1.41.scm.