老潘已转到http://www.panxingzhi.net/。所有旧文章如有改动,此处将不再更新。谢谢。 I've moved to http://www.panxingzhi.net/. Updates on old posts are not applied here. Thanks.

SICP-1.5 solution

I'll write the answers to the SICP exercises here, not everyone of them, though. I'm not planning to publish a book so I only write the ones I'm interested in, plus many stuff I found helpful or funny.

So here's the first one, the 1.5.

(define (p) (p))

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

(test 0 (p))

Most people seem to agree with the conclusion about the applicative-order one, so do I. The interpreter will keep evaluating the procedure p, in an endless manner. This is a typical situation where a recursion is without a proper ending condition.

Next comes the normal-order part. Well, most people do get the right answer, but they're being vague about the detailed substitute/eval process and they ignore the fact that if is a special form, rather than a combination.

In fact, after first round, (test 0 (p)) would be expanded to:

(if (= 0 0) 0 (p)).

Here comes the thing: according to the evaluation rule of normal-order, the interpreter “would first substitute operand expressions for parameters until it obtained an expression involving only primitive operators”. So at first I thought that since (p) in (if (= 0 0) 0 (p)) is NOT "an expression involving only primitive operators", it should be further expanded, thus lead to an endless recursion. But on second thought I checked the R5RS manual and here it is:

http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-7.html#%_idx_98

Bingo! if is a special form so the normal-order evaluation rule does not apply to it. (p) is never evaluated if the conditional expression is true.





4 条评论:

  1. 老潘, 2008-08-08 00:55:56  [回复]
    当然不是两个都是0。我已经说清楚了,applicative order会死循环。注意:applicative还没到if的时候,就已经死循环了。

    Okay我来用中文解释一下。程序的实际出发点是:
    (test 0 (p))

    如果是applicative order,解释器看到了这个式子会eval,test被eval成一个函数,0被eval成自身,(p)一eval就死循环了。注意这可还没到if呢。

    如果normal order呢?解释器这个"eval"行为会变成"substitute",即:
    (test 0 (p))
    -> (if (= 0 0) 0 (p)) ;替换了test

    注意由于normal order不先eval而是substitute,它反而绕过了eval (p)造成的死循环。接下来对if,normal order就不适用了。所以eval (= 0 0),得值0,程序结束。
  2. d???, 2008-08-07 11:14:19  [回复]
    我觉得还是有点问题,照你的看,2个都是0(说了normal-order evaluation rule does not apply to it,因此,它会结束),实际上,这段在跑的时候不会停.我的理解是,normal order会把式子完全展开,在展开的时候,if这里根本还没去apply,一直要到"until it obtained an expression involving only primitive operators"才会停。而如果是applicative-order,在展开的时候,if这里就是#t,所以0。
  3. 老潘, 2008-02-04 21:09:18  [回复]
    嗯 初学的时候还没有建立special form的概念 所以会有这样的问题 事后再看就是理所当然的了
  4. 3fen, 2008-02-03 20:00:01  [回复]
    刚开始看sicp
    这道题到你这算解释的更清楚了
    之前觉得两个都应该是无限的

添加评论