理解闭包和方法论

时间:2017-11-24 01:25:43

标签: javascript parsing closures interpreter evaluation

我正在建立一个解释器,现在我需要实现它来处理闭包。我很清楚这个概念,但我对他们为什么按照他们的方式进行设计有疑问。

关于如何设计/解释闭包,需要有三件事:

  1. 可变
  2. 变量绑定到
  3. 的逻辑体
  4. 在闭包实例化期间保存的环境,这是在评估闭包变量时要绑定到主体内的自由变量。
  5. 我理解为什么所有这些都是必需的,我只是想知道为什么在关闭创建时的替换是同样的事情时需要第3项?我有什么不考虑的吗?

    基本上我要问的是,为什么不在创建闭包时将自由变量替换为相应的环境值而不是完全传递环境?

1 个答案:

答案 0 :(得分:1)

我觉得有点晚了,但是哦......好吧......

这取决于您的计算模型(例如评估策略)。 如果所有数据结构[可以被变量绑定,并且实际上被包含]在您的语言中是不可变的,那么您的方法应该可行。 它适用于纯粹的词汇lisp方言(例如方案的功能子集),漂亮而流畅。

如果符合以下条件,则可能无效:

  • 您通过引用传递参数,正如评论中已经提到的那样。按价值打电话很好。对不可变对象的引用也没问题。
  • 您的环境绑定和/或查找会导致一些副作用。那会很奇特,但是谁知道呢?

另外,请注意,您不必将整个环境,只是函数体的自由变量(简单!)包围起来。

[我知道]将闭包实现为body + environment的唯一原因是:

  • 您可能希望将引用传递给可变对象。这发生了i.a.在js和python中使用词典;随着时间的推移关闭变化有点可怕,但是很好。

  • 您不需要编写替代功能。请注意,它必须保持范围正确,因此必须类似于您的评估函数[如果您的计算模型是替代的] - 那么为什么要重复自己呢?还有这种微妙的价值观:在应用顺序的情况下("急切的评价")当你替换身体中的价值时,你需要将它提升到表达谁的价值是事情(如果您实施LISP变体,请考虑符号 - 您不能替换值HI!,而是替换表达式(quote HI!)。这不适用于所有情况数据结构评估自己,如大多数LISP中的数字或真值。这些通常不是问题,但会为您的翻译带来一些复杂性,简单就是好

  • 绑定值可能是耗费内存的东西,并且您所包含的变量不止一次出现[作为自由变量] - 您的身体将显着更大(例如,您的值是位图或声音样本或一些巨大的矩阵或......你得到的图片)。与懒惰评估的计算重复类似的问题,但是内存,而不是时间。由于计算机存储器很大,这通常也不是问题。

我已经没有其他可能会破坏的想法,但是如果你不在检查你的计算模型"在纸上" (通过等式推理)你应该实现它并尝试最棘手的案例[如果适用的话]:副作用,懒惰评估,引用,可变对象,以上的组合。他们绝对不是障碍,只是值得检查的地方。 希望有帮助,祝你的翻译好运!

PS如果你想考虑这种东西,请查看defunctionalization("Defunctionalization at Work" Danvy和Nielsen是一本非常容易理解的读物,你应该没问题,第一部分可以获得灵感)