Compiler construction 仅将环境的相关子集传递给eval的方案解释器

Compiler construction 仅将环境的相关子集传递给eval的方案解释器,compiler-construction,functional-programming,lisp,scheme,interpreter,Compiler Construction,Functional Programming,Lisp,Scheme,Interpreter,是否有一种有效的方法来构建一个仅将环境的相关子集传递给递归eval调用的Scheme解释器 例如,考虑下面的表达式: (let ([x 1] [y 2]) (+ x 3)) 当我们计算(eval'(+x3)env)时,环境包含绑定{x:1,y:2}。如何编写一个高效的解释器,使环境只包含{x:1} 当然,通常我们无法事先知道是否要使用某个值。我要寻找的是一种可能基于编译器优化技术的粗略语法方法?-这比在每次递归调用eval时遍历大部分环境以过滤掉不相关的值更有效 (背景:我需要

是否有一种有效的方法来构建一个仅将环境的相关子集传递给递归
eval
调用的Scheme解释器

例如,考虑下面的表达式:

(let ([x 1]
      [y 2])
  (+ x 3))
当我们计算
(eval'(+x3)env)
时,环境包含绑定
{x:1,y:2}
。如何编写一个高效的解释器,使环境只包含
{x:1}

当然,通常我们无法事先知道是否要使用某个值。我要寻找的是一种可能基于编译器优化技术的粗略语法方法?-这比在每次递归调用
eval
时遍历大部分环境以过滤掉不相关的值更有效


(背景:我需要编写一个记忆方案解释器。)

当然:对于每个子表达式,计算该子表达式的值,并以某种方式将其附加到AST。然后,在每次递归调用
eval
时,仅将环境限制为要计算的表达式的自由变量

编译器通常在
lambda
边界处执行此操作,以避免创建保留对不必要值的引用的闭包,因为保留这些引用可能会阻止对象被GC调用。也就是说,对于下面的程序

(let ([x 1]
      [y 2])
  (lambda (z)  ;; free vars = {x}
    (+ x z))
lambda
表达式的闭包将包含
x
的值,但不包含
y
。但一般来说,这样做意味着您不能使用非常简单的“帧列表”环境表示;您可能需要将其展平(或至少复制和修剪)

有些实现在不再使用局部变量时(特别是在非尾部调用之前),也会将它们归零(闭包不包含的变量,您希望在寄存器或堆栈中看到的那种)。就是

(let ([x some-big-object])
  (f (g x) long-running-expression-not-involving-x))
可能会被翻译成与

(let ([x some-big-object])
  (let ([tmp1 (g x)])
    (set! x #f)
    (let ([tmp2 long-running-expression-not-involving-x])
      (f tmp1 tmp2))))

原因是一样的:尽早删除引用意味着可以更快地释放对象。(这也意味着它们不会被捕获的连续体抓住,类似于闭包案例。)谷歌“空间安全”获取更多信息。

的通用编译器优化将在这里实现这一点。不使用Y,因此可以简单地删除Y绑定


为了回答如何编写高效解释器的一般问题,我建议创建一个AST,然后使用各种优化技术(如部分解释器)将其多次传递,以尽可能地预计算和简化。

我认为这在很大程度上取决于您的中间表示方式。假设我从词汇环境的SICP评估器开始,“高效解释器”是一个矛盾修饰法。如果你想提高效率,你就要竭尽全力编写一个编译器。“我怎样才能成为最有效率的长跑运动员,但我的体重不能降到300磅以下?”尽管我用这种方式回答问题,但我并不热衷于写口译员。编写编译器生成记忆代码的想法同样受欢迎。@Kaz我不认为“高效的解释器”完全是自相矛盾的。探索如何使解释器更高效当然有教育价值,即使这只是编写编译器的一个步骤。请参阅第6章中的Lisp,它使用快速解释的目标作为编译的垫脚石。还有一个想法:不必实际过滤环境(慢!),您可以将自由变量作为参数传递给您的记忆代码,以便在比较时只考虑相关部分(和散列,如果你用散列表进行记忆的话)。但是,为了空间安全,你可能仍然需要过滤输入到表中的内容。为了确保我理解你评论中的想法:当我进行递归调用(syntax节点,env)时,我(1)获取存储在syntax节点中的自由变量列表,(2)在环境中查找每个变量的值,(3)构建这些变量的排序列表,我将其用作mem键。(在步骤(3)中,如果我想避免遍历这个新对象,即使是在哈希表匹配的情况下,我也可以使用“object DAG”/“value number”来构建它)相关问题中描述的想法。)