compiler-construction - 了解编译器中递归闭包的建模

标签 compiler-construction closures lisp

我得到了有关为类 lisp 语言建模递归闭包的两种方法的描述。假设我有以下代码:

(letrec ((f (fun (l) … (map f l) …)))) …)

对于对应于 f 的闭包,我可以:

  1. f 视为一个自由变量,并将其置于自己的环境中,从而导致循环闭包。
  2. 使用平面闭包,环境就是闭包,可以直接重用。

我使用的是平面闭包的概念,它在第一个单元格中存储一个指向函数的指针,在其余单元格中存储自由变量。但是我对第二个选项感到困惑,因为在我看来,第一次和第二次调用接收不同的参数。那么它们怎么可能获得相同的闭包并且不需要将递归调用作为自由变量包括在内来区分它们呢?

也许您可以解释一下在典型编译器的后续步骤中如何解决这个问题?

最佳答案

每次调用 f 都会为 l 创建一个新的闭包(假设词法范围)。 f 主体中的闭包通常不包含 f,但父级包含,因此您最终将查找调用堆栈。

我写了一篇更深入的帖子:http://cinigl.io/posts/nested-variable-scoping

关于compiler-construction - 了解编译器中递归闭包的建模,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43232861/

相关文章:

python - 为什么 python 在解释之前将源代码编译为字节码?

apache-flex - 如何在 AS3 中创建自定义 MouseEvent.CLICK 事件(将参数传递给函数)?

lisp - lisp 缺少哪些功能?

lisp - 在 Emacs Lisp 中获取指向列表元素的指针

c# - 独立的 C# 编译器

c++ - 一个空类和一个空结构是如何编译的?

gcc - 现代编译器如何使用 mmx/3dnow/sse 指令?

javascript - 我无法让 JavaScript 事件监听器正常工作

javascript - 为什么要使用 (function(){})() 或 !function(){}()?

在 COMMON LISP 中使用先序和中序重建树