Scheme中引用术语的自由变量的约束时间

时间:2016-05-03 16:07:53

标签: binding scheme eval quote free-variable

我试着理解Scheme中的引用现象是如何工作的。特别是,我想了解何时绑定引用术语的自由变量。

例如,当我写

(define q 'a)
(define a 42)
(eval q)

它返回42.因此我推断出绑定时间是在运行时。但在这种情况下,为什么这段代码失败

(let ((q 'a))
  (let ((a 42))
    (eval q)
  )
)

并返回

unbound variable:  a

有人可以解释一下引用术语的约束时间模型是什么(例如,与MetaOCaml相当吗?(我不这么认为))和define和let之间的区别?

2 个答案:

答案 0 :(得分:2)

Scheme具有词法范围规则,而不是动态绑定规则。

您的顶级define定义的行为就像在顶级词汇环境中创建绑定一样。

第二个代码片段实际上创建了两个词法环境,一个嵌套在另一个环境中。那么({em> not“when”)q被绑定的地方,a仍未绑定。但真正的问题是,eval使用了哪种环境?

您的实现表现得好像它使用定义环境或顶级环境,但肯定不是当前的词法环境,用于评估符号 'a,这是值q变量。 变量 q具有明确的绑定词汇环境,由其let表单创建 - 但符号 'a的位置在哪里s绑定驻留?我们怎么知道?

详细信息应该在文档中。

答案 1 :(得分:1)

首先,引用符号与字符串一样多,变量与字符串相同,字符序列与C语言语言(如Javascript)中的变量相同。他们没有任何共同点,因为他们生活在不同的世界。

eval不知道词汇变量,只知道全局变量。它知道要评估的结构中的词法变量。例如。

(eval '(let ((tmp (list q q))) 
          tmp)) 

q需要是全局的,但tmp是一个词法变量。

标准方案,又名R6RS,采用第二个参数,您可以选择哪些库应该可用。这些仍被认为是全球性的。

变量在运行时绑定。只要此优化不会破坏报告,实现就可以自由优化和不断折叠。

eval是一个强大的程序,除非它是解决问题最明智的方法,否则不应该使用它。在我17年的职业生涯中,我已经在生产代码中看到了两次,我认为这一次太多了。