Section 1.1

This commit is contained in:
Correl Roush 2014-05-05 09:27:03 -04:00
commit 448d4d00aa

243
1-1.scm Normal file
View file

@ -0,0 +1,243 @@
;; ====================================================================
;; SICP - 1.1: The Elements of Programming
;; ====================================================================
(define (square x)
(* x x))
(define (sum-of-squares a b)
(+ (square a) (square b)))
;; (define (abs x)
;; (cond ((< x 0) (- x))
;; ((= x 0) 0)
;; ((> x 0) x)))
(define (abs x)
(if (< x 0) (- x)
x))
(define (average x y)
(/ (+ x y) 2))
(define (sqrt x)
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x)
x)))
(define (improve guess x)
(average guess (/ x guess)))
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001))
(sqrt-iter 1.0 x))
;; ====================================================================
;; *Exercise 1.1:* 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
;; 10
(+ 5 3 4)
;; 12
(- 9 1)
;; 8
(/ 6 2)
;; 3
(+ (* 2 4) (- 4 6))
;; 10
(define a 3)
;; 3
(define b (+ a 1))
;; 4
(+ a b (* a b))
;; 19
(= a b)
;; #f
(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 following expression into prefix
;; form.
;;
;; 5 + 4 + (2 - (3 - (6 + 4/5)))
;; -----------------------------
;; 3(6 - 2)(2 - 7)
;; -------------------------------------------------------------------
(define ex1.2
(/ (+ 5 4 (- 2 (- 3 (+ 6 (/ 4 5)))))
(* 3 (- 6 2) (- 2 7))))
;; ===================================================================
;; *Exercise 1.3:* Define a procedure that takes three numbers as
;; arguments and returns the sum of the squares of the two larger
;; numbers.
;; -------------------------------------------------------------------
(define (ex1.3 a b c)
(cond ((and (> b a) (> c a)) (sum-of-squares b c))
((and (> a b) (> c b)) (sum-of-squares a c))
(#t (sum-of-squares a b))))
(define (ex1.3-fancy a b c)
(let* ((sorted (sort (list a b c) >))
(x (car sorted))
(y (cadr sorted)))
(+ (square x) (square y))))
;; ===================================================================
;; *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:
;;
(define (a-plus-abs-b a b)
((if (> b 0) + -) a b))
;; -------------------------------------------------------------------
;; When the function is called, the following will happen:
;;
;; * The first expression in the list, (if (> b 0) + -) will be
;; evaluated. Within it, (> b 0) will be evaluated first, and
;; based on the value of b, the result of the evaluation will be +
;; or -.
;; * The remaining expressions (a and b) will be evaluated to their
;; passed-in values.
;; * The resulting expression will be evaluated, e.g. (+ 3 2)
;; * The final result will be the result of applying the + or -
;; operator to the operands a and b
;; ===================================================================
;; *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:
;;
(define (p) (p))
(define (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? What behavior 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.)
;; -------------------------------------------------------------------
;; Applicative order evaluation will evaluate test, 0 and (p), then
;; evaluate the application of the operator test on its
;; operands. However, attempting to evaluate (p) will hang, as it is a
;; recursive function that never exits.
;;
;; Normal order evaluation will first apply the operator test on its
;; operands, which will then evaluate 0 in the if statment. The
;; conditional expression will succeed, and so the function will
;; return 0, never evaluating (p).
;; ===================================================================
;; *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'?" 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:
;;
;; (new-if (= 2 3) 0 5)
;; 5
;;
;; (new-if (= 1 1) 0 5)
;; 0
;;
;; Delighted, Alyssa uses `new-if' to rewrite the square-root program:
;;
;; (define (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.
;; -------------------------------------------------------------------
;; Calls to sqrt-iter will recurse indefinitely. This is because both
;; the then-clause and the else-clause passed to new-if will be
;; evaluated before the function new-if is applied.
;; ===================================================================
;; *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. 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:* 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
;;
;; x/y^2 + 2y
;; ----------
;; 3
;;
;; Use this formula to implement a cube-root procedure analogous to
;; the square-root procedure. (In section *Note 1-3-4:: we will see
;; how to implement Newton's method in general as an abstraction of
;; these square-root and cube-root procedures.)
;; -------------------------------------------------------------------