4 (defn sum-of-squares [x y]
5 (+ (square x) (square y)))
8 (sum-of-squares (+ a 1) (* a 2)))
14 ;; exercise 1.1: What is the result printed by the interpreter in response
15 ;; to each expression (in order) ?
23 (if (and (> b a) (< b (* a b)))
31 (+ 2 (if (> b a) b a)) ; 6
38 ;; exercise 1.2: Translate the given expression into prefix form
39 (/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 1 5)))))
40 (* 3 (- 6 2) (- 2 7))) ; -71/300
42 ;; exercise 1.3: Define a procedure that takes three numbers as
43 ;; arguments and returns the sum of the squares of
44 ;; the two larger numbers.
46 (cond (> b a) (sort3 b a c)
50 (defn sum-of-sq-of-two-largest [a b c]
51 (apply sum-of-squares (take 2 (sort3 a b c))))
53 ;; well, I cheated above. Let me use only the constructs introduced
54 ;; so far in the book. (follows after the sicp meetup #2 on 28/mar/2010.
55 (defn sum-of-square-of-two-largest [a b c]
58 (sum-of-squares a b) ; a > b > c
62 (sum-of-squares b c))))
64 ;; exercise 1.4: Observe that our model of evaluation allows for
65 ;; combinations whose operators are compound
66 ;; expressions. Use this observation to describe the
67 ;; behavior of the following procedure:
68 ;; (defn a-plus-abs-b [a b]
69 ;; ((if (> b 0) + -) a b))
71 If b is positive, we do (+ a b) and if it is negative, we do (- a b).
72 This makes use of the fact that the first element in a list is an
73 operand. Here, the operand is chosen based on other operators.
76 ;; exercise 1.5: Ben Bitdiddle has invented a test to determine
77 ;; whether the interpreter he is faced with is
78 ;; using applicative-order evaluation or normal-order
79 ;; evaluation. He defines the following two procedures:
86 ;; Then he evaluates the expression
90 ;; What behavior will Ben observe with an interpreter that uses
91 ;; applicative-order evaluation?
93 In the case of applicative order evaluation, the test gets into
94 and infinite loop (eventually using all the stack), as the parameters
95 are evaluated before they are actualy used in the function.
97 ;; What behavior will he observe with an interpreter that uses
98 ;; normal-order evaluation? Explain your answer.
100 It will print 0, as (p) is not evaluated in this case.
103 ;; 1.1.7 Square root finding using Newton's method
107 (defn improve [guess x]
108 (average guess (/ x guess)))
110 (defn good-enough? [guess x]
111 (< (myabs (- (square guess) x)) 0.001))
113 (defn sqrt-iter [guess x]
114 (if (good-enough? guess x)
116 (sqrt-iter (improve guess x)
123 ;; Alyssa P. Hacker doesn't see why if needs to be provided as a special form.
124 ;; ``Why can't I just define it as an ordinary procedure in terms of cond?''
125 (defn new-if [predicate then-clause else-clause]
126 (cond predicate then-clause
129 (new-if (= 3 2) 0 5) ; 5
130 (new-if (= 1 1) 0 5) ; 0
132 ;; Delighted, Alyssa uses new-if to rewrite the square-root program:
134 (defn sqrt-iter [guess x]
135 (new-if (good-enough? guess x)
137 (sqrt-iter (improve guess x)
140 ;; what happens when Alyssa attempts to use this to compute square roots? Explain.
142 Since `new-if' is a function, when it is called from sqrt-iter, the parameters
143 are evaluated before it gets called. good-enough? will return a false unless
144 the guess and x are almost the same. guess evaluated to the initial value of
145 guess. sqrt-iter gets evaluated, but gets into an infinite loop. The predicate
146 will have no effect.)
148 ;; Exercise 1.7: The good-enough? test used in computing square roots will not
149 ;; be very effective for finding the square roots of very small numbers. Also,
150 ;; in real computers, arithmetic operations are almost always performed with
151 ;; limited precision. This makes our test inadequate for very large numbers.
152 ;; Explain these statements, with examples showing how the test fails for small
153 ;; and large numbers.
155 user> (sqrt (square 0.001))
157 user> (sqrt (square 0.2))
159 user> (sqrt (square 0.01))
161 user> (sqrt (square 0.02))
163 user> (sqrt (square 10))
165 user> (sqrt (square 100))
167 user> (sqrt (square 200))
169 user> (sqrt (square 2))
171 user> (sqrt (square 0.1))
173 user> (sqrt (square 0.01))
175 user> (sqrt (square 10000))
177 user> (sqrt (square 20000))
179 user> (sqrt (square 200000))
181 user> (sqrt (square 20000000))
183 user> (sqrt (square 20000000000))
185 user> (sqrt (square 200000.012))
187 user> (sqrt (square 2000000.123))
189 user> (sqrt (square 200000000.123))
191 user> (sqrt (square 2000000000.123))
193 user> (sqrt (square 20000000000.123))
195 user> (sqrt (square 2000000000000.123))
198 ;; An alternative strategy for implementing good-enough? is to watch how guess
199 ;; changes from one iteration to the next and to stop when the change is a very
200 ;; small fraction of the guess.
201 (defn sqrt-iter [old-guess new-guess x]
202 (if (good-enough? old-guess new-guess x)
204 (sqrt-iter new-guess (improve new-guess x)
207 (defn improve [guess x]
208 (average guess (/ x guess)))
213 (defn good-enough? [old-guess new-guess x]
214 (< (/ (myabs (- new-guess old-guess)) new-guess) 0.0001))
219 user> (sqrt (square 0.01))
221 user> (sqrt (square 0.001))
222 0.0010000000000000117
223 user> (sqrt (square 0.0001))
224 1.0000000000082464E-4
225 user> (sqrt (square 0.02))
227 user> (sqrt (square 0.002))
228 0.0020000000000000235
229 user> (sqrt (square 4))
231 user> (sqrt (square 20))
233 user> (sqrt (square 25))
244 ;; exercise 1.8: cube root
245 (defn improve [guess x]
246 (/ (+ (/ x (square guess)) (* 2 guess)) 3))
248 (defn cubert-iter [old-guess new-guess x]
249 (if (good-enough? old-guess new-guess x)
251 (cubert-iter new-guess (improve new-guess x)
255 (cubert-iter x 1.0 x))
258 user> (cuberoot (cube 2))
260 user> (cuberoot (cube 10))
262 user> (cuberoot (cube 9))
264 user> (cuberoot (cube 0.001))
266 user> (cuberoot (cube 0.0001))
271 ;; hiding the non-public procedure definitions
272 (defn- sqrt-iter [guess x]
273 (if (good-enough? guess x)
275 (sqrt-iter (improve guess x)
278 (defn- improve [guess x]
279 (average guess (/ x guess)))
284 (defn- good-enough? [guess x]
285 (< (myabs (- (square guess) x)) 0.001))