Scheme中的闭包如何工作?

时间:2011-04-09 22:20:53

标签: lambda scope scheme closures

我在Racket / DrScheme中测试了以下代码:

(define (makem)
    (define x 34)
    (list (lambda () (set! x (+ x 1)) x)
          (lambda () (set! x (+ x 1)) x))
)

(define f (car (makem)))
(define f2 (car (cdr (makem))))

> (f)
35
> (f2)
35            ; I thought this would give me 36
> (f)
36
> (f)
37
>

在函数调用中创建的每个lambda都会获取其范围内每个变量的副本吗?它是否像某种隐含的让?我期望lambdas有一些指向它们创建范围的指针,使它们能够访问堆栈变量,但这告诉我,因为f和f2似乎有不同的x副本。究竟发生了什么?

1 个答案:

答案 0 :(得分:6)

您曾两次致电(makem),因此您使用两个不同的x副本创建了两个不同的环境。如果您拨打(makem)一次,就像这样:

(define m (makem))
(define f (car m))
(define f2 (car (cdr m)))

然后ff2确实会共享x m中的{{1}}。