(define (sqrt x)
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001))
(define (improve guess x)
(average guess (/ x guess)))
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(sqrt-iter 1.0 x))
我似乎无法围绕内部街区结构。如果define的语法是:(define procedure arg arg body)。您如何在顶级定义中定义所有其他局部范围变量?
定义是否存在语法异常?
答案 0 :(得分:0)
define
的语法不是(define procedure arg .. body)
。它是(define (name . args) defines ... body1 bodyn ...)
,是(define name (lambda args defines ... body1 bodyn ...))
的快捷方式。请注意,x ...
表示零或更多,因此(lambda (a b) (+ a b))
可以正常,但(lambda (a b) (define (test) (+ a b)))
不是。
内部define
由lambda
语法处理。基本上它会被重写为letrec
。所以
(define (sqrt x)
(define (good-enough? guess x)
(< (abs (- (square guess) x)) 0.001))
(define (improve guess x)
(average guess (/ x guess)))
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(sqrt-iter 1.0 x))
变为:
(define sqrt
(lambda (x)
(letrec ((good-enough? (lambda (guess x)
(< (abs (- (square guess) x)) 0.001)))
(improve (lambda (guess x)
(average guess (/ x guess))))
(sqrt-iter (lambda (guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))))
(sqrt-iter 1.0 x))))
显然,使用本地define
的原因是让它比letrec
更平坦,更易读。保持相同的名称,即使它们是由实现的不同部分处理的完全不同的动物,也是方案程序员的简化,但是如果你试图弄清楚方案实现如何工作则更难理解和理解。