Lambda在Scheme中制作程序

时间:2019-09-29 17:30:26

标签: scheme sicp

我正在通过“ 计算机程序的结构和解释”来学习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匹配,则lambdaa必须用括号加以限制。

但是在示例代码中,请勿使用括号。

运行此代码时,会发生错误。

这是错误:

***'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 这样写?

1 个答案:

答案 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))))过程,您将其称为其代码的一部分。