考虑以下程序,其中尚未定义foo
和bar
。
(define (f)
foo)
(if #t
(display "Hello!")
bar)
这是一个有效的Scheme计划吗?Scheme程序是否允许有未绑定的变量,只要这些变量从未被求值?
否:
"引用未绑定变量"是违反语法的;(r6rs报告9.1(
"引用未绑定的变量是错误的"(r7rs报告4.1.1(
问题代码可以通过Scheme实现进行评估,但不是Scheme程序,如果包含在程序中,则该实现应发出错误信号:
$ scheme
> (if #t (display "Hello!") bar)
Hello!
> (top-level-program (import (rnrs))
(if #t (display "Hello!") bar))
Exception: attempt to reference unbound identifier bar
>
备注
(top-level-program )
是Chez Scheme的扩展,可用于交互进入Scheme程序。
r6rs报告中与方案程序、变量和未绑定含义相关的摘录(原始斜体强调,添加粗体(:
5.1程序和库
Scheme程序由顶级程序和一组库组成
5.2变量、关键字和区域
命名位置的标识符被称为变量,并被称为绑定到该位置。。。每提到一个标识符都是指建立最内部的标识符的绑定包含用途的区域的。。。如果标识符没有绑定,则称其为未绑定。
9.1.基元表达式类型/变量引用
由变量组成的表达式(第5.2节(是变量引用。。。引用未绑定变量是语法冲突。
5.5.语法冲突
实现必须检测违反语法的行为。语法冲突是关于库主体、顶级主体的语法。。。如果程序中的顶级或库形式在语法上不正确,那么。。。不得开始执行该顶级程序或库。
因此Scheme程序可以包含未绑定的变量,但符合标准的实现不能开始评估程序,即使永远无法尝试评估变量。
没有,但有,但没有…
解释最近使用的术语Scheme程序、未绑定和变量方案报告,似乎答案是否定的(参考我的其他答案(。
但这取决于关于示例代码的另一个假设——if
具有其通常的含义作为语言定义报告中描述的语法关键字。
由于Scheme程序中的标识符可以隐藏关键字,因此这是有效的bar
似乎未绑定的方案程序:
(import (rnrs))
(let-syntax ([if (syntax-rules ()
[(if e1 e2 _) (if e1 e2)])])
(if #t
(display "Hello!")
bar))
因此:
$ scheme
> (top-level-program (import (rnrs))
(let-syntax ([if (syntax-rules ()
[(if e1 e2 _) (if e1 e2)])])
(if #t
(display "Hello!")
bar)
(if #f
(display "Hello!")
bar)))
Hello!
>