解答这道题的关键在于了解到应用序和正则序之间的区别(书本的 1.1.5 小节有详细的说明)。
首先,可以确定的是,无论解释器使用的是什么求值方式,调用 (p)
总是进入一个无限循环(infinite loop),因为函数 p
会不断调用自身:
(define (p) (p))
具体到解释器中,执行 (p)
调用会让解释器陷入停滞,最后只能强制将解释器进程杀掉:
1 ]=> (p)
^Z
[1]+ 已停止 mit-scheme
$ killall mit-scheme
在应用序中,所有被传入的实际参数都会立即被求值,因此,在使用应用序的解释器里执行 (test 0 (p))
时,实际参数 0
和 (p)
都会被求值,而对 (p)
的求值将使解释器进入无限循环,因此,如果一个解释器在运行 Ben 的测试时陷入停滞,那么这个解释器使用的是应用序求值模式。
另一方面,在正则序中,传入的实际参数只有在有需要时才会被求值,因此,在使用正则序的解释器里运行 (test 0 (p))
时, 0
和 (p)
都不会立即被求值,当解释进行到 if
语句时,形式参数 x
的实际参数(也即是 0
)会被求值(求值结果也是为 0
),然后和另一个 0
进行对比((= x 0)
),因为对比的值为真(#t
),所以 if
返回 0
作为值表达式的值,而这个值又作为 test
函数的值被返回。
因为在正则序求值中,调用 (p)
从始到终都没有被执行,所以也就不会产生无限循环,因此,如果一个解释器在运行 Ben 的测试时顺利返回 0
,那么这个解释器使用的是正则序求值模式。
Note
另一个需要说明的地方是『形式参数』和『实际参数』两个名词。
对于一个函数来说,它接受的参数的局部名被称为形式参数。
而调用函数时传入的表达式,被称为实际参数。
比如说,对于函数 (define (square x) (* x x))
来说, x
就是形式参数,当进行调用 (square 2)
时, 2
就是形式参数 x
的实际参数。
当人们只说『参数』而不说明它是『形式参数』还是『实际参数』时,他们一般指的是『形式参数』,但是具体还是要看上下文来决定。