Exercise 1.1
The Question
Below is a sequence of expressions. What is the result printed by the interpreter in response to each expression? Assume that the sequence is to be evaluated in the order in which it is presented.
10
(+ 5 3 4)
(- 9 1)
(/ 6 2)
(+ (* 2 4) (- 4 6))
(define a 3)
(define b (+ a 1))
(+ a b (* a b))
(= a b)
(if (and (> b a) (< b (* a b)))
b
a)
(cond ((= a 4) 6)
((= b 4) (+ 6 7 a))
(else 25))
(+ 2 (if (> b a) b a))
(* (cond ((> a b) a)
((< a b) b)
(else -1))
(+ a 1))
The Answer
We'll break this into chunks of each top-level expression. This will help us examine each expression in enough detail (though mainly to print each expression's result).
Exercise 1.2
The Question
Translate the following into prefix form:
\[ \frac{5 + 4 + (2 - (3 - (6 + \frac{4}{5}))}{3(6 - 2)(2 - 7)} \]
The Answer
We can translate this by recursively grouping values by the outermost common operation. This means we start with the fraction, and divide the numerator and denominator. Then we add for the numerator and multiply for the denominator and so on and so forth. Going through with this exercise, we finally come up with:
Exercise 1.3
The Question
Define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers.
The Answer
Prerequisites
Since we need to square twice, we'll first define the procedure square
(define (square x)
(* x x))
(square 7)
49
As well as max
to find the max of two numbers:
(define (max a b)
(if (> a b) a b))
Testing max
:
Exercise 1.4
The Question
Observe that our model of evaluation allows for combinations whose operators are compound expressions. Use this observation to describe the behaviour of the following procedure:
(define (a-plus-abs-b a b)
((if (> b 0) + -) a b))
The Answer
Adding a positive number and subtracting a negative number has the same effect
as adding the absolute value of a number. We are able to change the procedure as
observed. Thus +
is returned as the procedure if b
is greater than 0, and -
otherwise.
Exercise 1.5
The Question
Ben Bitdiddle has invented a test to determine whether the interpreter he is faced with is using applicative-order evaluation or normal-order evaluation. He defines the following two procedures:
(define (p) (p))
(define (test x y)
(if (= x 0) 0 y))
Then he evaluates the expression:
(test 0 (p))
What behaviour will Ben observe with an interpreter that uses applicative-order
evaluation? What behaviour will he observe with an interpreter that uses
normal-order evaluation? Explain your answer. (Assume that the evaluation rule
for the special form if
is the same whether the interpreter is using normal or
applicative order: the predicate expression is evaluated first, and the result
determines whether to evaluate the consequent or the alternative expression.)
Exercise 1.6
The Question
Alyssa P. Hacker doesn't see why if
needs to be provided as a special form. "Why
can't I just define it as an ordinary procedure in terms of cond
?" she asks.
Alyssa's friend Eva Lu Ator claims this can indeed be done, and she defines a
new version of if
:
(define (new-if predicate then-clause else-clause)
(cond (predicate then-clause)
(else else-clause)))
Eva demonstrates the program for Alyssa:
Exercise 1.7
The Question
The good-enough?
test used in computing square roots will not be very effective
for finding the square roots of very small numbers. Also, in real computers,
arithmetic operations are almost always performed with limited precision. This
makes our test inadequate for very large numbers. Explain these statements, with
examples showing how the test fails for small and large numbers. An alternative
strategy for implementing good-enough?
is to watch how guess
changes from one
iteration to the next and to stop when the change is a very small fraction of
the guess. Design a square-root procedure that uses this kind of end test. Does
this work better for small and large numbers?
Exercise 1.8
The Question
Newton's method for cube roots is based on the fact that if \(y\) is an approximation to the cube root of \(x\), then a better approximation is given by the value \[\frac{x/y^2 + 2y}{3}\] Use this formula to implement a cube-root procedure analogous to the square-root procedure.
The Answer
This exercise essentially requires us to rewrite the improve
implementation from
the previous exercise for cube roots:
Exercise 1.9
The Question
Each of the following two procedures defines a method for adding two positive
integers in terms of the procedures inc
, which increments its argument by \(1\),
and dec
, which decrements its argument by \(1\).
(define (+ a b)
(if (= a 0) b (inc (+ (dec a) b))))
(define (+ a b)
(if (= a 0) b (+ (dec a) (inc b))))
Using the substitution model, illustrate the process generated by each procedure
in evaluating (+ 4 5)
. Are these processes iterative or recursive?
Exercise 1.10
The Question
The following procedure computes a mathematical function called Ackermann's function:
(define (A x y)
(cond ((= y 0) 0)
((= x 0) (* 2 y))
((= y 1) 2)
(else (A (- x 1) (A x (- y 1))))))
What are the values of the following expressions?
(A 1 10)
(A 2 4)
(A 3 3)
Consider the following procedures, where A
is the procedure defined above:
(define (f n) (A 0 n))
(define (g n) (A 1 n))
(define (h n) (A 2 n))
(define (k n) (* 5 n n))
Give concise mathematical definitions for the functions computed by the
procedures f
, g
, and h
for positive integer values of \(n\). For example, (k n)
computes \(5n^2\) .
Exercise 1.11
The Question
A function \(f\) is defined by the rule that
\[f(n) = \begin{cases} n & \text{if n < 3} \\ f(n - 1) + 2f(n - 2) + 3f(n - 3) & \text{if n} \ge 3 \\ \end{cases}\]
Write a procedure that computes \(f\) by means of a recursive process. Write a procedure that computes \(f\) by means of an iterative process.
The Answer
Recursive Implementation
The rule directly spells out our recursive implementation:
Exercise 1.12
The Question
The following pattern of numbers is called Pascal's triangle.
1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 . . .
The numbers at the edge of the triangle are all 1, and each number inside the triangle is the sum of the two numbers above it. Write a procedure that computes elements of Pascal's triangle by means of a recursive process.