这两条线有什么区别? 我想做一个加法器函数。 结果第一行有效,但第二行无效。 我是计划的新手,谢谢。
(define (make-adder num) (lambda (x) (+ num x)))
(define (make-adder num) (define (foo x) (+ num x)))
lambda
定义一个函数并返回它。 define
定义一个值(可能是一个函数),但不返回它。所以你对这两种形式定义的函数的等价性是正确的,但你需要在第二个中返回foo
:
(define (make-adder num)
(define (foo x)
(+ num x))
foo)
形式
(define (name args ...)
defines ... body ...)
只是语法糖:
(define name
(lambda (args ...)
defines ... body ...))
现在在 lambda 形式中,您可以使用零个或多个局部
define
,然后跟随至少一个身体表达。在您的第一个示例中,您有零个定义和一个主体表达式,即一旦应用就会变成闭包的 lambda 表达式。
你的第二个版本有一个局部变量定义
foo
但是因为没有主体表达式,所以这不是有效的 Scheme 代码。为了等同于第一个代码,您需要将刚刚定义的变量作为主体,返回新创建的闭包,如下所示:
(define (make-adder num)
(define (foo x)
(+ num x))
foo)
现在两个版本是一样的。也可以完全写出来,这样Scheme实现就不需要像这样展开糖了:
(define make-adder
(lambda (num)
(define foo (lambda (x) (+ num x)))
foo))
当然使用语法糖并没有坏处,但是像 The little Schemer 这样的书避免使用缩写形式只是因为它可能给人的印象是过程不仅仅是评估过程对象的变量。例如。在
(a b c)
中a
只是一个变量,就像b
和c
一样。唯一的区别是需要 a
评估过程,就像在 (+ c d)
c
和 d
需要是数字以避免运行时错误。