本文描述了两种为类lisp语言的递归闭包建模的方法假设我有以下代码:
(letrec ((f (fun (l) … (map f l) …)))) …)
对于
f
对应的闭包,我可以:将
f
视为自由变量,并将其放在自己的环境中,从而导致循环闭包。对于平面闭包,环境就是闭包,可以直接重用。
我使用的是平面闭包的概念,它在第一个单元格中存储指向函数的指针,在其他单元格中存储自由变量但我对第二个选项感到困惑,因为在我看来,第一个和第二个调用接收不同的参数那么它们怎么可能得到相同的闭包,而不需要将递归调用作为自由变量来区分它们呢?
也许你可以解释一下在一个典型的编译器的未来步骤中如何解决这个问题?
最佳答案
每次调用f
将创建一个新的闭包,其值为l
(假设词法范围)。f
主体中的闭包通常不包含f
,但父闭包将包含,因此您将最终查找调用堆栈。
我写了一篇关于这个的文章:http://cinigl.io/posts/nested-variable-scoping
关于compiler-construction - 了解编译器中递归闭包的建模,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43232861/