sicp,1.5题的疑问

2013-07-21 21:08:36 +08:00
 kier
(define (p) (p))

(define (test x y) (if (= x 0) 0 y))

Then he evaluates the expression

(test 0 (p))


网上搜索,几乎所有的答案都说正则序会执行if判断后,返回0,不会去计算(p),我的疑问是,书上说的正则序会替换直到得到一个只包含基本运算符的表达式,那么由于p的存在,应该会陷入无穷的替换之中阿,为什么会替换停止
3468 次点击
所在节点    程序员
6 条回复
clww
2013-07-21 21:31:28 +08:00
因为还没有到计算的那一步就结束啦
Golevka
2013-07-21 21:36:10 +08:00
不知道你所谓的正则序是不是call-by-name的意思, CBN会按照substitution rule完全展开之后才开始求值, 因此展开if时(p)是不会被求值的
Golevka
2013-07-21 21:43:08 +08:00
更正: 展开if时(p)是不会被求值的 => 展开test时(p)不会被求值. 接下来(p)被代换到(if ...)的里面, 由于(= x 0) => (= 0 0)为#t所以(p)作为false branch就不会被求值了
kier
2013-07-21 21:58:28 +08:00
@Golevka 可能是我对正则序的理解有误,我以为的是,它会一直代换,直到整个表达式只有最基本的运算符才截止
那么另一个说得通的解释是,正则序代换并不是无脑的字符替换,它也是建立在逻辑判断上的,当判断if为真的时候,那么就不代换else子句的内容了?
standin000
2013-07-21 22:59:43 +08:00
正则序是么意思?eval函数很短的,看看就明白执行原理。
codepiano
2013-07-22 00:38:43 +08:00
@kier sicp里面讲正则序应用序的部分在语言组织上有些不清楚,楼主可能没看明白具体的定义
应用序定义:“解释器首先对运算符和各个运算对象求值,而后将得到的过程应用于得到的实际参数”
正则序定义:“先不求出运算对象的值,直到实际需要它们的值时再去做”
当使用应用序求(test 0 (p))时,解释器会对0和(p)进行求值,会造成无限循环
而使用正则序求(test 0 (p))时,解释器会对test函数进行展开,将0和(p)代入到test函数的定义中去,在需要时才对0和(p)进行求值,(test 0 (p))代换为:(if (= 0 0) 0 (p))),此处并未对(p)进行求值
而程序执行过程中,返回if的第一个分支,所以(p)永远没有执行

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/76503

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX