Exercise 1.3
Exercise 1.5
If the interpreter is using applicative-order, when running (test 0 (p)), first will evaluate the operand, which is a procedure, (p). This, according to the definition of p, will result in infinite loop. Just the case with MIT-Scheme.
With normal-order evaluation, it doesn’t first evaluate (p), rather, it substitute the operand (p) into the body of test. And (if (= x 0) will make test return 0.
Exercise 1.6
Since the interpreter uses applicative-order, as stated above, in the call to new-if, all three of good-enough?, guess, (sqrt-iter …) must first be evaluated. The call to (sqrt-iter …) will then never stop, leading to infinite loop.
Exercise 1.7
I don’t know now how the test fails for small and large numbers.
[UPDATE]
Eli Bendersky has a good explanation, the idea to use a relative ratio instead of hard-coded 0.001 is very pretty. BTW, (sqrt 92400000000000000) and (sqrt 0.0005) works well on my laptop with the original solution.
The updated version of sqrt:
Exercise 1.8
(define (sq x) (* x x))
(define (sum-of-sq x y) (+ (sq x) (sq y)))
(define (>= x y) (or (> x y) (= x y)))
(define (sq-of-two-larger a b c)
(if (>= a b)
(if (>= b c) (sum-of-sq a b) (sum-of-sq a c))
(if (>= a c) (sum-of-sq a b) (sum-of-sq b c))))
Exercise 1.5
If the interpreter is using applicative-order, when running (test 0 (p)), first will evaluate the operand, which is a procedure, (p). This, according to the definition of p, will result in infinite loop. Just the case with MIT-Scheme.
With normal-order evaluation, it doesn’t first evaluate (p), rather, it substitute the operand (p) into the body of test. And (if (= x 0) will make test return 0.
Exercise 1.6
Since the interpreter uses applicative-order, as stated above, in the call to new-if, all three of good-enough?, guess, (sqrt-iter …) must first be evaluated. The call to (sqrt-iter …) will then never stop, leading to infinite loop.
Exercise 1.7
I don’t know now how the test fails for small and large numbers.
[UPDATE]
Eli Bendersky has a good explanation, the idea to use a relative ratio instead of hard-coded 0.001 is very pretty. BTW, (sqrt 92400000000000000) and (sqrt 0.0005) works well on my laptop with the original solution.
The updated version of sqrt:
(define (sqrt x)
(sqrt-iter 1.0 x))
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (update guess x) x)))
;; (define (good-enough? guess x)
;; (< (abs (- (square guess) x ))
;; 0.001))
(define (good-enough? guess x)
(< (abs (- guess (update guess x)))
0.0001))
(define (square x)
(* x x))
(define (abs x)
(if (< x 0)
(- x)
x))
(define (update guess x)
(average guess (/ x guess)))
(define (average x y)
(/ (+ x y) 2))
Exercise 1.8
(define (cube-root x)
(cube-root-rec 1.0 x))
(define (cube-root-rec guess x)
(if (good-enough? guess x)
guess
(cube-root-rec (update guess x) x)))
(define (good-enough? guess x)
(< (abs (- (update guess x) guess))
0.0001))
(define (update guess x)
(/ (+ (/ x (square guess)) (* 2 guess)) 3))
(define (square x)
(* x x))
(define (abs x)
(if (< x 0)
(- x)
x))