(cond (< x 0) (- x)
:else x))
-;; exercise 1.1: What is the result printed by the interpreter in response
-;; to each expression (in order) ?
-
-(def a 3)
-(def b (+ a 1))
-
-(+ a b (* a b)) ; 19
-(= a b) ; false
-
-(if (and (> b a) (< b (* a b)))
- b
- a) ; 4
-
-(cond (= a 4) 6
- (= b 4) (+ 6 7 a)
- :else 25) ; 16
-
-(+ 2 (if (> b a) b a)) ; 6
-
-(* (cond (> a b) a
- (< a b) b
- :else -1)
- (+ a 1)) ; 16
-
-;; exercise 1.2: Translate the given expression into prefix form
-(/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 1 5)))))
- (* 3 (- 6 2) (- 2 7))) ; -71/300
-
-;; exercise 1.3: Define a procedure that takes three numbers as
-;; arguments and returns the sum of the squares of
-;; the two larger numbers.
-(defn sort3 [a b c]
- (cond (> b a) (sort3 b a c)
- (< b c) (sort3 a c b)
- :else [a b c]))
-
-(defn sum-of-sq-of-two-largest [a b c]
- (apply sum-of-squares (take 2 (sort3 a b c))))
-
-;; well, I cheated above. Let me use only the constructs introduced
-;; so far in the book. (follows after the sicp meetup #2 on 28/mar/2010.
-(defn sum-of-square-of-two-largest [a b c]
- (if (> a b)
- (if (> b c)
- (sum-of-squares a b) ; a > b > c
- (sum-of-squares a c))
- (if (> a c)
- (sum-of-squares b a)
- (sum-of-squares b c))))
-
-;; exercise 1.4: Observe that our model of evaluation allows for
-;; combinations whose operators are compound
-;; expressions. Use this observation to describe the
-;; behavior of the following procedure:
-;; (defn a-plus-abs-b [a b]
-;; ((if (> b 0) + -) a b))
-(comment
- If b is positive, we do (+ a b) and if it is negative, we do (- a b).
- This makes use of the fact that the first element in a list is an
- operand. Here, the operand is chosen based on other operators.
- )
-
-;; exercise 1.5: 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:
-;; (defn p [] (p))
-;; (defn test [x y]
-;; (if (= x 0)
-;; 0
-;; y))
-;;
-;; Then he evaluates the expression
-;;
-;; (test 0 (p))
-;;
-;; What behavior will Ben observe with an interpreter that uses
-;; applicative-order evaluation?
-(comment
- In the case of applicative order evaluation, the test gets into
- and infinite loop (eventually using all the stack), as the parameters
- are evaluated before they are actualy used in the function.
- )
-;; What behavior will he observe with an interpreter that uses
-;; normal-order evaluation? Explain your answer.
-(comment
- It will print 0, as (p) is not evaluated in this case.
- )
-
;; 1.1.7 Square root finding using Newton's method
(defn average [x y]
(/ (+ x y) 2))
(defn sqrt [x]
(sqrt-iter 1.0 x))
-;; exercise 1.6
-;; 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?''
-(defn new-if [predicate then-clause else-clause]
- (cond predicate then-clause
- :else else-clause))
-
-(new-if (= 3 2) 0 5) ; 5
-(new-if (= 1 1) 0 5) ; 0
-
-;; Delighted, Alyssa uses new-if to rewrite the square-root program:
-
-(defn sqrt-iter [guess x]
- (new-if (good-enough? guess x)
- guess
- (sqrt-iter (improve guess x)
- x)))
-
-;; what happens when Alyssa attempts to use this to compute square roots? Explain.
-(comment
- Since `new-if' is a function, when it is called from sqrt-iter, the parameters
- are evaluated before it gets called. good-enough? will return a false unless
- the guess and x are almost the same. guess evaluated to the initial value of
- guess. sqrt-iter gets evaluated, but gets into an infinite loop. The predicate
- will have no effect.)
-;; Exercise 1.7: 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.
-(comment
- user> (sqrt (square 0.001))
- 0.031260655525445276
- user> (sqrt (square 0.2))
- 0.20060990407779591
- user> (sqrt (square 0.01))
- 0.03230844833048122
- user> (sqrt (square 0.02))
- 0.0354008825558513
- user> (sqrt (square 10))
- 10.000000000139897
- user> (sqrt (square 100))
- 100.00000025490743
- user> (sqrt (square 200))
- 200.000000510076
- user> (sqrt (square 2))
- 2.0000000929222947
- user> (sqrt (square 0.1))
- 0.10032578510960607
- user> (sqrt (square 0.01))
- 0.03230844833048122
- user> (sqrt (square 10000))
- 10000.0
- user> (sqrt (square 20000))
- 20000.0
- user> (sqrt (square 200000))
- 200000.0
- user> (sqrt (square 20000000))
- 2.0E7
- user> (sqrt (square 20000000000))
- 2.0E10
- user> (sqrt (square 200000.012))
- 200000.012
- user> (sqrt (square 2000000.123))
- 2000000.123
- user> (sqrt (square 200000000.123))
- 2.00000000123E8
- user> (sqrt (square 2000000000.123))
- 2.000000000123E9
- user> (sqrt (square 20000000000.123))
- 2.0000000000123E10
- user> (sqrt (square 2000000000000.123))
- 2.000000000000123E12
- )
;; 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.
user> (sqrt 81)
9.000000000007091
)
-;; exercise 1.8: cube root
-(defn improve [guess x]
- (/ (+ (/ x (square guess)) (* 2 guess)) 3))
-
-(defn cubert-iter [old-guess new-guess x]
- (if (good-enough? old-guess new-guess x)
- new-guess
- (cubert-iter new-guess (improve new-guess x)
- x)))
-(defn cuberoot [x]
- (cubert-iter x 1.0 x))
-
-(comment
-user> (cuberoot (cube 2))
-2.000000000012062
-user> (cuberoot (cube 10))
-10.000000000000002
-user> (cuberoot (cube 9))
-9.000000000053902
-user> (cuberoot (cube 0.001))
-0.001000000000000962
-user> (cuberoot (cube 0.0001))
-1.000000000000001E-4
-user>
-)
;; section 1.1.8
;; hiding the non-public procedure definitions
(defn- sqrt-iter [guess x]