首页 文章

为什么scheme找到一个用“define”而不是“let”定义的变量

提问于
浏览
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绑定时绑定x . 这是因为当定义函数时它也定义在顶层,因此当方案去搜索其最近的封闭环境时,let环境实际上并没有“封闭”,因为它仍然在“top-”开始搜索水平”?

3 回答

  • 1

    词汇范围是Scheme的核心功能 . 使用词法作用域,您始终可以确定哪些绑定对于函数是可见的,因为它们是在定义函数的位置可见的那些 . 相比之下,动态范围设计倾向于产生难以预见且同样难以调试的意外情况 .

  • 4

    Scheme使用词法范围,而不是动态范围 . 所以 x undefinedTest 看到的 x 是从该函数中词汇可见的,在这种情况下,正如您已经指出的那样,它是顶级作用域 .

  • 1

    当定义 undefinedTest 时,它包含了定义它的环境;鉴于它是在顶层定义的,它只有"see"其形式参数 y 和全局环境 - 并且此时全局环境不包含 x . 这就是因为Scheme是词法范围的 .

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

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

相关问题