Scheme中两种make-adder定义的差异咨询:为何第一种可行第二种不行?
两行Scheme代码的差异解析
先看你的两行代码:
- 正常运行的版本:
(define (make-adder num) (lambda (x) (+ num x)))
- 无法工作的版本:
(define (make-adder num) (define (foo x) (+ num x)))
核心差异在于返回值
第一行的
make-adder函数,接受参数num后直接返回一个匿名lambda函数。这个lambda会捕获外部的num变量,调用(make-adder 5)时会得到一个能给输入值加5的函数,比如((make-adder 5) 3)会返回8——因为返回的lambda是可执行的闭包。第二行的
make-adder仅在内部定义了具名函数foo,但没有返回这个foo函数。Scheme中函数默认返回最后一个表达式的结果,而define是用于定义变量/函数的特殊形式,它的返回值通常是未定义的(不同Scheme实现表现可能不同,但肯定不是你需要的foo)。所以调用(make-adder 5)后,得不到可用的加法函数,自然无法工作。
怎么修复第二行代码
只要在内部定义完foo后,把它作为返回值即可:
(define (make-adder num) (define (foo x) (+ num x)) foo)
修改后,make-adder的行为就和第一行完全一致了——foo是具名闭包,lambda是匿名闭包,本质都是捕获了num的函数,功能没有区别。
内容的提问来源于stack exchange,提问作者Callum Ethan
相关产品推荐
相关产品推荐

