问题可以找here .
在书中,我发现一个正常的顺序评估的描述是:
“替代评估模型不会评估操作数,直到需要它们的值。相反,它会首先用操作数表达式替换参数,直到它获得仅涉及原始运算符的表达式,然后才会执行评估。”
我还找到了另外一个描述,简而言之:“完全展开然后缩小”。
在练习中,我认为p
的定义类似于(lambda () (p))
,
它永远不会扩展为原始运算符,因此永远不会终止。
但是,另一方面,在谷歌搜索了这个问题的一些答案之后,似乎正常的订单评估应该终止,因为它只根据需要评估事物,而实际上 (p)
不会被评估.
所以我认为“扩展”和“评估”之间一定有一些区别,解释器在这里所做的是评估事物。
到底有什么区别,或者 有没有我遗漏的要点?
另一个问题:我应该说“(p)
计算为(p)
”还是“(p)
扩展为(p)
"?
最佳答案
你是对的,如果要求计算 (p)
,应用顺序计算器不会终止。但是,手头的问题提到 if
具有特定的评估语义,该语义由应用程序和正常顺序评估程序共享。具体来说,“假设无论解释器使用的是正常顺序还是应用顺序,特殊形式 if 的求值规则都是相同的:首先对谓词表达式求值,结果决定是求值后项表达式还是替代表达式。”
练习的代码是
(define (p) (p))
(define (test x y)
(if (= x 0)
0
y))
正在考虑的测试是
(test 0 (p))
正常顺序评估是“完全扩展然后减少”选项。在正常顺序评估下,(test 0 (p))
完全展开为
(test 0 (p)) ==
(if (= 0 0)
0
(p))
由于 if
具有上述语义,并且扩展中的测试条件为 (= 0 0)
,为真,正常顺序求值器确定计算结果,即 0
,因此表达式的值为 0
。
然而,使用应用顺序求值,求值 (test 0 (p))
的第一步是求值表达式 test
, 0
和 (p)
,然后调用 (“apply”,因此 “applicative”) test
的值与评估 0
和 (p)
产生的值。由于 (p)
的评估不会完成,因此 (test 0 (p))
的评估也不会完成。
关于lisp - 寻求对 SICP 练习 1.5 的一些解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16036139/