为什么(define lambda (lambda (x) x))中的x出现未绑定错误?
问题原因分析
你遇到的运行差异本质是不同Scheme实现对语法关键字的解析规则、define绑定的作用域规则不同导致的。
MIT Scheme 11.2、Chez Scheme 9.5 报错的原因
- 这类实现严格遵循Lisp-1设计,语法关键字和普通变量共享同一个命名空间,且
define定义的变量的作用域覆盖当前整个包含该define语句的完整作用域,而非仅作用于define语句之后的部分。 - 当解析
(define lambda (lambda (x) x))时,实现首先会标记当前作用域下的lambda标识符将绑定到你即将定义的变量,直接覆盖全局的lambda语法关键字。 - 接下来需要对define右侧的表达式
(lambda (x) x)求值:此时lambda已经不再是特殊语法,而是普通变量,因此整个表达式会被识别为普通函数调用:即调用lambda指向的函数,传入两个参数(x)和x。 - Scheme的函数调用规则要求先对所有参数求值,第二个参数是未绑定的变量
x,因此直接抛出x未绑定的错误。
Racket 7.2、Guile 3.0.1 运行正常的原因
这两类实现对语法关键字和普通变量的解析规则做了特殊处理:
语法关键字的解析优先级高于普通变量绑定,在解析define右侧表达式时,lambda仍然优先被识别为语法关键字,正常求值为匿名函数,求值完成之后才将lambda变量绑定到该函数,因此不会出现解析错误。
内容的提问来源于stack exchange,提问作者Flux
相关产品推荐
相关产品推荐

