谁能给解释一下 SICP 习题1.5
anbutu
2008-05-09
网上的答案居然有好几种版本,我越看越糊涂~
我的理解: 无论哪种情况,首先都会替换为下面的形式: ((if (= 0 0) 0 (p)) 然后,在"Applicative-order"的时候,要先计算 (p),这样就导致了死循环。 然而,在"Normal-order"的时候,(p)只有在需要的时候才会被求值,但if的条件为假,所以(p)不会被求值。 |
|
Lich_Ray
2008-05-10
并非如此。如果照你这样说,那在应用序求值的语言中递归岂不是始终是死循环?谓词部分总是先求值的。关键在于 (test 0 (p)) 这一句。如果是应用序求值的语言会进入死循环,是在执行 (p) 的时候进入的;使用正则序求值的语言,正如你所想的,直接返回 0。
|
|
anbutu
2008-05-12
"并非如此。如果照你这样说,那在应用序求值的语言中递归岂不是始终是死循环?" 因为 if 是个special form,所以不会死循环,如果换成 sicp 中用cond 实现的那个 new-if 就会死循环了。 |
|
Jamsa
2008-05-23
我在两种不同的解释器上试了,都不能正确的执行,不知道什么原因,我猜想:
以applicative order方式执行时,解释器先会对操作数求值。 如果是normal order,则会先展开表达式。 如果以applicative order方式执行,则在对(p)求值时会发生错误。 如果以normal order执行,则展(p)时也会进入死循环。 |
|
Jamsa
2008-05-23
在这个人http://eli.thegreenplace.net/2007/06/21/sicp-section-11/的笔记中找到:
However, with normal order evaluation, (p) is not evaluated until it’s actually needed, which never happens, because the comparison of x with 0 suceeds and the call just returns 0. |
|
cuigang
2008-06-03
http://www.cppblog.com/cuigang/archive/2007/12/26/39635.html
解决这个问题主要是“正则序”(Normal order)以及“应用序”(Applicative order)展开一个组合式的规则,仔细研究了MIT 6.001课程讲义,网上的各种答案,以及中英文版。我认为,正则序以类似广度优先的方式进行展开。而应用序优先计算子表达式,类似与深度优先。那么对于这个问题,正则序会展开为 => (if (= 0 0) 0 (p)) => (if #t 0 (p)) 接着,由于这是一个if的special form(特殊形式),就会被展开为 0 而应用序,由于(p)一直可以递归代换,从一开始就会进入一个无限递归中去。 简言之,由于应用序的原因,在 test 表达式 还没有展开为 if 特殊形式(special forms)时, (p)已经陷入了无限递归。 |
|
逸宇行空
2008-06-20
同意2楼说的
应用序求值会先对(P)求值而后应用,也就是说先计算(p),如果(p)终止则会把0和求值(p)得到的值代入test得到if语句,但因为求值(P)不会中止,所有程序不会终止 正则序求值会先应用,也就是说把0和(p)代入test,然后对if谓词求值为true并输出0,从而避免对(P)求值 所以楼主说的 “无论哪种情况,首先都会替换为下面的形式: ((if (= 0 0) 0 (p))” 是错的 |
|
glacjay
2009-02-18
正则序和应用序说的都是函数调用,if 又不是函数调用。
|
|
freizl
2009-08-09
- applicative order evaluation
the expression values will be parsed before running the application. - normal order evaluation expressions will be passed as needed in the application. 所以在 normal order eval 的时候,不需要eval 对象(p),直接出结果0 而在 applicative order eval时,由于(p) 无限递归而陷入死循环 |
|
silentpassing
2011-01-09
一开始就没弄清概念
|