我正在通过“ 计算机程序的结构和解释”来学习Scheme
在第1.3.2章使用lambda构造过程中。
我这样理解lambda。
与lambda匹配的值写在lambda的括号之外。
((lambda (x) (+ x 4) 4) ; (x) is matched to 4, result is 8
但是在 SICP 中,另一个示例代码有所不同。
代码是:
(define (sum x y) (+ x y))
(define (pi-sum a b)
(sum (lambda (x) (/ 1.0 (* x (+ x 3))))
a
(lambda (x) (+ x 4))
b
))
(pi-sum 3 6)
我认为,如果(lambda (x) (/ 1.0 (* x (+ x 3))))
要与a
匹配,则lambda
和a
必须用括号加以限制。
但是在示例代码中,请勿使用括号。
运行此代码时,会发生错误。
这是错误:
***'sum: expects only 2 arguments, but found 4'***
当我使用更多这样的括号时:
(define (sum x y) (+ x y))
(define (pi-sum a b)
(sum ((lambda (x) (/ 1.0 (* x (+ x 3))))
a)
((lambda (x) (+ x 4))
b)
))
(pi-sum 2 6) ; result is 10.1
代码已运行。
由于 SICP 的示例代码,我感到困惑。
我对lambda
的原则正确吗?
如果我是对的,为什么 SICP 这样写?
答案 0 :(得分:3)
表示使用1.3.1中的总和。在第77页上(实际上从77开始到78结束)看起来像这样:
(define (sum term a next b)
(if (> a b)
0
(+ (term a)
(sum term (next a) next b))))
如您所见,它看起来与sum
只是两个数字加起来有很大不同。您在pi-sum
中也有错字:
(define (pi-sum a b)
(sum (lambda (x) (/ 1.0 (* x (+ x 2)))) ; multiplied by 2, not 3!
a
(lambda (x) (+ x 4))
b))
(* 8 (pi-sum 1 1000))
; ==> 3.139592655589783
因此,这里的要点是您可以传递lambda而不是命名过程。因为(define (name . args) body ...)
只是(define name (lambda args body ...))
传递(lambda args body ...)
而不是定义并传递名称的语法糖,所以只是一个相等的重构。
围绕变量(+)
或lambda ((lambda args body ...))
的括号调用操作符表达式计算的任何过程。这不是您想要的,因为您传递了sum
用作抽象的过程。 sum
可以根据您传递的内容进行乘法或任意数量的操作。 sum
中的term
中的过程是(lambda (x) (/ 1.0 (* x (+ x 2))))
过程,您将其称为其代码的一部分。