我正在为Scheme写一个很小的评估员。
我需要使用替换模型编写评估程序,因此不会使用set!
之类的赋值。
但是由于我仍然需要在某个地方存储原始过程和用户 - define
变量,我是否需要一个环境?如果是这样,替代模型和环境模型之间有什么区别?
感谢。
答案 0 :(得分:2)
否 - 对于基于替换的普通评估者,您不需要一个环境。这是因为只要你有一个绑定(例如,当你执行函数调用时),你立即用名称替换名称,因此不需要保持name->值映射。实际上,您可以通过缓存它们并在以后执行它们来查看环境,以避免替换所涉及的开销。有关此视图后面的教科书,请参阅PLAI - 事实上,它从替换到替换缓存,并且稍后才会将术语更改为环境
但请注意,使用set!
的问题与所有这些无关。当您考虑set!
时,首先需要明确您所谈论的set!
的级别:如果您使用的语言是实施而不是实现本身,然后可以添加任何类型的可变值 - 例如,在Racket中,您可以使用boxes,这足以在语言中实现set!
。这通常在基于环境的评估程序中完成,其中环境类型从映射名称更改为值,映射名称到位置(实现为框或类似的可变值)。但这并不是必要的:你仍然可以使用基于替代的评估器来做到这一点,其中这些框正在成为你所替代的价值领域的一部分。举一个具体的例子,你可以从像(使用类似方案的语言)这样的表达式开始:
(let ((x 1))
(begin (set! x 2)
(set! x 3)))
而不是将1
替换为x
,而是分配一个包含1
的框,然后替换相同框导致
(begin (set! #<box> 2)
(set! #<box> 3))
其中两个#<box>
es是该单个框。 (请注意,这不是我正在讨论的实现代码,而是您正在评估的语言中的表达式。)通常不会这样做的原因是它可能令人困惑 - 您需要将值表示为框可以替换,那些框不是源用户程序的一部分,但它们是解释器应该处理的值(例如,最后#<box>
是返回值 - 但它是你的值想要返回,而不是盒子),你需要注意盒子的身份(例如,上面的两个盒子是第一个{em>相同框的解释是很重要的{ {1}}在第二个中可见。
如果您只是在学习编写口译员,那么不建议这样做。如果是这种情况,那么我建议你只看一下那本教科书。
答案 1 :(得分:1)
是的,你仍然需要一个环境,因为就像你说你需要能够存储变量等。
替换模型是一种帮助您了解如何评估给定过程的方法。例如,您可以定义平方函数
(define (square x) (* x x))
使用替换模型,如果您调用
(square 4)
然后将4替换为函数定义中每次出现的x,以便
(* 4 4) => 16
环境用于显示变量和状态在解释器中的存储方式。简而言之,替换模型用于帮助您评估过程,同时使用环境来查看解释器将如何记住用户在使用解释器时可能定义的变量和定义。