3 (defn square [x] (* x x))
5 (defn sum-of-squares [x y]
6 (+ (square x) (square y)))
9 (sum-of-squares (+ a 1) (* a 2)))
12 "find absolute value of x"
20 ;; exercise 1.1: What is the result printed by the interpreter in response
21 ;; to each expression (in order) ?
29 (if (and (> b a) (< b (* a b)))
37 (+ 2 (if (> b a) b a)) ; 6
44 ;; exercise 1.2: Translate the given expression into prefix form
45 (/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 1 5)))))
46 (* 3 (- 6 2) (- 2 7))) ; -71/300
48 ;; exercise 1.3: Define a procedure that takes three numbers as
49 ;; arguments and returns the sum of the squares of
50 ;; the two larger numbers.
52 (cond (> b a) (sort3 b a c)
56 (defn sum-of-sq-of-two-largest [a b c]
57 (apply sum-of-squares (take 2 (sort3 a b c))))
59 ;; well, I cheated above. Let me use only the constructs introduced
60 ;; so far in the book. (follows after the sicp meetup #2 on 28/mar/2010.
61 (defn sum-of-square-of-two-largest [a b c]
64 (sum-of-squares a b) ; a > b > c
68 (sum-of-squares b c))))
70 ;; exercise 1.4: Observe that our model of evaluation allows for
71 ;; combinations whose operators are compound
72 ;; expressions. Use this observation to describe the
73 ;; behavior of the following procedure:
74 ;; (defn a-plus-abs-b [a b]
75 ;; ((if (> b 0) + -) a b))
77 If b is positive, we do (+ a b) and if it is negative, we do (- a b).
78 This makes use of the fact that the first element in a list is an
79 operand. Here, the operand is chosen based on other operators.
82 ;; exercise 1.5: Ben Bitdiddle has invented a test to determine
83 ;; whether the interpreter he is faced with is
84 ;; using applicative-order evaluation or normal-order
85 ;; evaluation. He defines the following two procedures:
92 ;; Then he evaluates the expression
96 ;; What behavior will Ben observe with an interpreter that uses
97 ;; applicative-order evaluation?
99 In the case of applicative order evaluation, the test gets into
100 and infinite loop (eventually using all the stack), as the parameters
101 are evaluated before they are actualy used in the function.
103 ;; What behavior will he observe with an interpreter that uses
104 ;; normal-order evaluation? Explain your answer.
106 It will print 0, as (p) is not evaluated in this case.
109 ;; 1.1.7 Square root finding using Newton's method
113 (defn improve [guess x]
114 (average guess (/ x guess)))
116 (defn good-enough? [guess x]
117 (< (abs (- (square guess) x)) 0.001))
119 (defn sqrt-iter [guess x]
120 (if (good-enough? guess x)
122 (sqrt-iter (improve guess x)
129 ;; Alyssa P. Hacker doesn't see why if needs to be provided as a special form.
130 ;; ``Why can't I just define it as an ordinary procedure in terms of cond?''
131 (defn new-if [predicate then-clause else-clause]
132 (cond predicate then-clause
135 (new-if (= 3 2) 0 5) ; 5
136 (new-if (= 1 1) 0 5) ; 0
138 ;; Delighted, Alyssa uses new-if to rewrite the square-root program:
140 (defn sqrt-iter [guess x]
141 (new-if (good-enough? guess x)
143 (sqrt-iter (improve guess x)
146 ;; what happens when Alyssa attempts to use this to compute square roots? Explain.
148 Since `new-if' is a function, when it is called from sqrt-iter, the parameters
149 are evaluated before it gets called. good-enough? will return a false unless
150 the guess and x are almost the same. guess evaluated to the initial value of
151 guess. sqrt-iter gets evaluated, but gets into an infinite loop. The predicate
152 will have no effect.)
154 ;; Exercise 1.7: The good-enough? test used in computing square roots will not
155 ;; be very effective for finding the square roots of very small numbers. Also,
156 ;; in real computers, arithmetic operations are almost always performed with
157 ;; limited precision. This makes our test inadequate for very large numbers.
158 ;; Explain these statements, with examples showing how the test fails for small
159 ;; and large numbers.
161 user> (sqrt (square 0.001))
163 user> (sqrt (square 0.2))
165 user> (sqrt (square 0.01))
167 user> (sqrt (square 0.02))
169 user> (sqrt (square 10))
171 user> (sqrt (square 100))
173 user> (sqrt (square 200))
175 user> (sqrt (square 2))
177 user> (sqrt (square 0.1))
179 user> (sqrt (square 0.01))
181 user> (sqrt (square 10000))
183 user> (sqrt (square 20000))
185 user> (sqrt (square 200000))
187 user> (sqrt (square 20000000))
189 user> (sqrt (square 20000000000))
191 user> (sqrt (square 200000.012))
193 user> (sqrt (square 2000000.123))
195 user> (sqrt (square 200000000.123))
197 user> (sqrt (square 2000000000.123))
199 user> (sqrt (square 20000000000.123))
201 user> (sqrt (square 2000000000000.123))
204 ;; An alternative strategy for implementing good-enough? is to watch how guess
205 ;; changes from one iteration to the next and to stop when the change is a very
206 ;; small fraction of the guess.
207 (defn sqrt-iter [old-guess new-guess x]
208 (if (good-enough? old-guess new-guess x)
210 (sqrt-iter new-guess (improve new-guess x)
213 (defn improve [guess x]
214 (average guess (/ x guess)))
219 (defn good-enough? [old-guess new-guess x]
220 (< (/ (abs (- new-guess old-guess)) new-guess) 0.0001))
225 user> (sqrt (square 0.01))
227 user> (sqrt (square 0.001))
228 0.0010000000000000117
229 user> (sqrt (square 0.0001))
230 1.0000000000082464E-4
231 user> (sqrt (square 0.02))
233 user> (sqrt (square 0.002))
234 0.0020000000000000235
235 user> (sqrt (square 4))
237 user> (sqrt (square 20))
239 user> (sqrt (square 25))
250 ;; exercise 1.8: cube root
254 (defn improve [guess x]
255 (/ (+ (/ x (square guess)) (* 2 guess)) 3))
257 (defn cubert-iter [old-guess new-guess x]
258 (if (good-enough? old-guess new-guess x)
260 (cubert-iter new-guess (improve new-guess x)
264 (cubert-iter x 1.0 x))
267 user> (cuberoot (cube 2))
269 user> (cuberoot (cube 10))
271 user> (cuberoot (cube 9))
273 user> (cuberoot (cube 0.001))
275 user> (cuberoot (cube 0.0001))
280 ;; hiding the non-public procedure definitions
281 (defn- sqrt-iter [guess x]
282 (if (good-enough? guess x)
284 (sqrt-iter (improve guess x)
287 (defn- improve [guess x]
288 (average guess (/ x guess)))
293 (defn- good-enough? [guess x]
294 (< (abs (- (square guess) x)) 0.001))