2

所以这里有一个关于方案变量绑定的问题。假设我有以下功能:

(define undefinedTest (lambda (y) (list x y)))

当在 Guile-Scheme 2.0.3 中运行时,这将警告 x 是一个未绑定的变量。如果我然后执行以下语句

> (let ((x 'something)) (undefinedTest 'else))

我会得到一个错误和调试它的选项。但是,如果我执行以下语句:

> (define x 'something)
> (undefinedTest 'else)

我得到了(其他)的预期答案。为什么scheme在顶层定义时能够绑定x,但在let绑定时不能。这是因为当函数被定义时,它也是在顶层定义的,所以当scheme去搜索它最近的封闭环境时,let环境实际上并没有“封闭”,因为它仍然在“top-等级”?

4

3 回答 3

5

Scheme 使用词法作用域,而不是动态作用域。所以sees 是从x该函数中词法可见的,在这种情况下,正如您已经注意到的那样,它是顶级范围。undefinedTestx

于 2012-10-08T18:46:01.347 回答
1

undefinedTest被定义时,它包含了它被定义的环境;鉴于它是在顶层定义的,它只会“看到”它的形式参数y和全局环境 - 并且全局环境此时不包含x。之所以如此,是因为 Scheme 是词法范围的。

我在 Racket 中测试了问题中的代码,第一行因错误而失败:expand: unbound identifier in module in: x- 这意味着它甚至不是 Racket 解释的有效定义。

相同的示例适用于具有动态作用域的语言,Scheme 使用词法作用域(又名静态作用域)。

于 2012-10-08T21:21:44.890 回答
1

词法作用域是 Scheme 的核心特性。使用词法作用域,您总是可以分辨出哪些绑定对函数是可见的,因为它们是在定义函数时可见的绑定。相比之下,动态作用域倾向于产生难以预见且同样难以调试的意外。

于 2012-10-08T22:53:52.833 回答