【发布时间】:2022-01-23 17:34:01
【问题描述】:
我最近冒险进入了编写 Scheme 解释器的美妙领域,但我遇到了一个障碍:闭包。据我了解,它们封装了一个本地环境,其中包含一个在每次调用闭包时都会恢复的过程(这可能不完全正确)。我似乎在网上找不到任何地方的问题是闭包是如何正式定义的,即在 EBNF 语法中。我见过的大多数例子都说闭包是一个零参数的过程,它有一个嵌套在 let 表达式中的 lambda 表达式。这是定义 Scheme 闭包的唯一方式吗?更重要的是,如果没有正式的方法来正式定义一个闭包,你如何真正解释它?如果将所有 let 表达式转换为 lambda 会发生什么?例如,如果我这样声明一个闭包
(define (foo) (let ((y 0)) (λ (x) (…))))
然后赋值给一个变量
(define bar (foo))
这是按什么顺序评估的?从我所见,当foo 被声明时,它存储了一个指向父环境的指针,并声明了它自己的环境。如果我打电话给(bar),我应该立即在保存的本地环境中替换吗?
【问题讨论】:
-
闭包是语义问题,而不是语法问题。语法的定义不会显示它们的迹象。
-
@molbdnilo 那么有语义定义吗?我主要只是想知道如何告诉我的解释器“好的,这是一个闭包。”?
-
据我所知,Scheme 报告中没有定义,但 R. Kent Dybvig 的(因 Chez Scheme 成名)dissertation 中有很多有趣的细节。
-
Metalinguistic Abstraction 中的章节SICP 解释了您所需要的一切。看看
make-procedure。 -
看看我的this 回答是否有任何帮助。它以 13-15 行伪代码显示了原始的 McCarthy 的 Lisp,并增加了支持闭包(“funarg 设备”)。