This is the first post in my long-promised series of follow-up posts to The Education of a Programmer. I must have started this post at least 5 times, and each time I read the first sections of SICP. I can't really come up with words to do it justice—Abelson and the Sussmans describe the core concepts of computer programs in the most concise yet understandable way I've ever seen. Since I can't improve on the original, these posts will just be a sort of running diary as I work through the exercises in the book. And without further ado...
Exercise 1.1
In this exercise, we are asked to manually evaluate each expression as if we were the interpreter.
My Answer | Interpreter's Answer |
---|---|
10 | 10 |
12 | 12 |
8 | 8 |
3 | 3 |
6 | 6 |
(this was sort of a trick question - the interpreter doesn't print anything when it evaluates define expressions) |
|
see above | |
19 | 19 |
#f | #f |
4 | 4 |
16 | 16 |
6 | 6 |
16 | 16 |
Exercise 1.2
In this exercise, we are asked to convert a mathematical expression into prefix notation.
(/
(+ 5 4
(- 2
(- 3
(+ 6
(/ 3 4)))))
(* 3
(- 2 6)
(- 2 7)))
Exercise 1.3
In this exercise, we are asked to define a procedure that takes three numbers as parameters and returns the sum of the square of the two largest parameters. If you were starting from scratch, the solution would look something like this:
(define
(sum-of-squares-for-two-largest a b c)
(cond ((and (< a b) (< a c)) (+ (* b b) (* c c)))
((and (< b c) (< b c)) (+ (* a a) (* c c)))
(else (+ (* a a) (* b b)))))
But that's not very clean. There's too much repeated logic, and it's not very readable; we need some abstraction. The most obvious abstraction is to create a square
procedure that looks something like this:
(define
(square a)
(* a a))
Using this new procedure, we can rewrite our sum-of-squares-for-two-largest
procedure like so:
(define
(sum-of-squares-for-two-largest a b c)
(cond ((and (< a b) (< a c)) (+ (square b) (square c)))
((and (< b c) (< b c)) (+ (square a) (square c)))
(else (+ (square a) (square b)))))
That's better, but there's still room for improvement: we can create a sum-of-squares
procedure that looks like this:
(define
(sum-of-squares a b)
(+ (square a) (square b)))
Look at that: we created the same procedures that the authors walked us through creating earlier this chapter. Using our new sum-of-squares
procedure, sum-of-squares-for-two-largest
looks like this:
(define
(sum-of-squares-for-two-largest a b c)
(cond ((and (< a b) (< a c)) (sum-of-squares b c))
((and (< b c) (< b c)) (sum-of-squares a c))
(else (sum-of-squares a b))))
Exercise 1.4
In this exercise, we are asked to describe what the following procedure is doing.
(define (a-plus-abs-b a b)
((if (> b 0) + -) a b))
This procedure is summing a and the absolute value of b. The (if (> b 0) + -)
tells us that the procedure being applied to the arguments will differ based on whether b is positive or non-positive. When it's non-positive, b will be subtracted from a, which is functionally equivalent to always adding the absolute value of b to a.
Exercise 1.5
- Applicative-order
- This will result in an infinite loop, because the interpreter will attempt to evaluate
p
, which is recursive and has no exit conditions - Normal-order
- This will return 0 because the interpreter will evaluate the
if
before deciding whether to evaluatep
or return 0, and the results of theif
will indicate it should return 0
Back to flipping out...