练习 1.5

解答这道题的关键在于了解到应用序和正则序之间的区别(书本的 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 的实际参数。

当人们只说『参数』而不说明它是『形式参数』还是『实际参数』时,他们一般指的是『形式参数』,但是具体还是要看上下文来决定。

讨论

blog comments powered by Disqus