1.1.1 表达式

ex1.1

直接在解释器输入表达式就能得到结果:

>> 10
>> 12
>> 8
>> 3
>> 6
>> a
>> b
>> 19
>> #f
>> 4
>> 16
>> 6
>> 16

1.1.2 命名和环境

ex1.2

(/ (+ 5
       4
       (- 2 (- 3 (+ 6 (/ 4 5)))))
    (* 3
       (- 6 2)
       (- 2 7)))

计算结果是:-0.24666666666666667, 或者 -37/150


1.1.3 组合式的求值

ex1.3

(define (square x) (* x x))

(define (sumsquares x y) (+ (square x) (square y)))

(define (sqsumlargest a b c)
        (cond  
                ((and (>= a c) (>= b c)) (sumsquares a b))
                ((and (>= b a) (>= c a)) (sumsquares b c))
                ((and (>= a b) (>= c b)) (sumsquares a c))))
(sqsumlargest 1 2 3)
>> 13
(sqsumlargest 1 1 1)
>> 2
(sqsumlargest 1 2 2)
>> 8
(sqsumlargest 1 1 2)
>> 5

1.1.4 复合过程

ex1.4

if语句返回 - 或+,然后应用于操作数。

(define (a-plus-abs-b a b)
    ((if (> b 0) + -) a b))
(a-plus-abs-b 1 -3)
((if (> -3 0) + -) 1 -3)
((if #f + -) 1 -3)
(- 1 -3)

>> 4

(a-plus-abs-b 1 3)
((if (> 3 0) + -) 1 -3)
((if #t + -) 1 3)
(+ 1 3)

>> 4

1.1.5 过程应用的代换模型

ex1.5

使用应用顺序评估,(测试0(p))的评估永远不会终止,因为(p)无限扩展到自身:

(test 0 (p))

(test 0 (p))

(test 0 (p))

使用正态顺序评估,表达式逐步评估为0:

(test 0 (p))

(if (= 0 0) 0 (p))

(if #t 0 (p))

0

1.1.6 条件表达式和谓词

ex1.6

Alyssa 的 new-if 定义:

(define (new-if predicate then-clause else-clause)
    (cond (predicate then-clause)
          (else else-clause)))

先使用 new-if 重写平方根:

(define (average x y) (/ (+ x y) 2))
(define (square x) (* x x))
(define (improve guess x) (average guess (/ x guess)))
(define (good-enough? guess x) (< (abs (- (square guess) x)) 0.001))
(define (sqrt-iter guess x)
  (if (good-enough? guess x)
      guess
      (sqrt-iter (improve guess x) x)))
(define (sqrt x) (sqrt-iter 1.0 x))
(sqrt 9)
(sqrt (+ 100 37))
(sqrt (+ (sqrt 2) (sqrt 3)))
(square (sqrt 1000))

(define (new-if predicate then-clause else-clause)
  (cond (predicate then-clause)
        (else else-clause)))
(new-if (= 2 3) 0 5)
(new-if (= 1 1) 0 5)
(define (new-sqrt-iter guess x)
  (new-if (good-enough? guess x)
          guess
          (sqrt-iter (improve guess x) x)))
(define (new-sqrt x) (new-sqrt-iter 1.0 x))
(if (= (    sqrt 9)
       (new-sqrt 9))
    1 0)
(if (= (    sqrt (+ 100 37))
       (new-sqrt (+ 100 37)))
    1 0)
(if (= (    sqrt (+ (    sqrt 2) (    sqrt 3)))
       (new-sqrt (+ (new-sqrt 2) (new-sqrt 3))))
    1 0)
(if (= (square (    sqrt 1000))
       (square (new-sqrt 1000)))
    1 0)

>> 3.00009155413138
>> 11.704699917758145
>> 1.7739279023207892
>> 1000.000369924366
>> 5
>> 0
>> 1
>> 1
>> 1
>> 1

1.1.7 实例: 采用牛顿法求平方根

ex1.7

当计算小值的平方根时,0.001的绝对容差非常大。例如,在我使用的系统上,(sqrt 0.0001)产生0.03220324381282134而不是预期的0.01(误差超过200%)。

(sqrt 0.0001)

>> 0.03230844833048122

另一方面,对于非常大的radicand值,机器精度不能表示大数之间的微小差异。该算法可能永远不会终止,因为最佳猜测的平方不会在radicand的0.001范围内,并且尝试改进它将继续产生相同的猜测[即(改进猜测x)将等于猜测]。尝试(sqrt 1000000000000)[12个0],然后尝试(sqrt 10000000000000)[13个0]。在我的64位英特尔机器上,12个零点几乎立即产生答案,而13个零点进入无限循环。

(sqrt 1000000000000)

>>> 1000000.0
(sqrt 10000000000000)

>>>

使用替代策略,sqrt对小数和大数都有效。

(define (good-enough? guess x) (= guess (improve guess x)))
(sqrt 100000000000000000000)

>> 10000000000.0
(sqrt 0.00000000000000000009)

>> 0.0000000003

1.1.8 过程作为黑箱抽象

ex1.8

首先,将题目给定的算式转换成前序表达式:

(/ (+ (/ x (square y)) (* 2 y))
   3)
(define (cube x) (* x x x))

(define (square x) (* x x))

(define (cube-root x)(cube-root-iter 1.0 x))

(define (cube-root-iter guess x)          
    (if (good-enough? guess x)              
        guess
        (cube-root-iter (improve guess x) x)))

(define (good-enough? guess x) (< (abs (- (cube guess) x)) 0.001))

(define (improve guess x)(/ (+ (/ x (square guess)) (* 2 guess)) 3))

(define (square x) (* x x))1 ]=> (cube-root (* 3 3 3))
(cube-root (* 3 3 3))

>> 3.0000005410641766

(cube-root (* 5 5 5))

>> 5.000000000287929

(cube-root (* 7 7 7))

>> 7.000001795382107