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