shceme学习:continuation(3)阴阳谜题

本篇分析continuation的一个著名例子"阴阳迷题",这是由David Madore先生提出的,原谜题如下:

(let* ((yin ((lambda (foo) (display "@") foo) (call/cc (lambda (bar) bar))))
       (yang ((lambda (foo) (display "*") foo) (call/cc (lambda (bar) bar)))))
  (yin yang))

这里引用了http://www.ibm.com/developerworks/cn/linux/l-schm/part3/中的一些简化手段将其中的lambda表达式定义为过程,使其看起来更清晰:

(define bar (lambda (bar) bar))
(define foox (lambda (foo) (display "@") foo))
(define fooy (lambda (foo) (display "*") foo))

则上面的繁琐的表达式可以变成为:

 (let* ((yin (foox (call/cc bar)))
       (yang (fooy (call/cc bar))))
  (yin yang))

将let*改变成let,使其进一步简化为:

  (let ((yin (foox (call/cc bar))))
     (let ((yang (fooy (call/cc bar))))
  (yin yang)))

 这里要说明的一点是,链接处介绍的最后一个简化也就是下面这个:

最后将let去掉,继而成为:
((foox (call/cc bar)) (fooy (call/cc bar)))

其实是错误的.

Ok,我们开始人肉解释器的运行:

(let ((yin (foox (call/cc bar))))
    (let ((yang (fooy (call/cc bar))))
(yin yang)))

首先注意到(call/cc bar)会返回一个continuation,这里将第一行和第二行的continuation分别标识为c1,c2. 所以上面代码相当于:

(let ((yin c1));输出@
    (let ((yang c2));输出*
(yin yang)))

而(yin yang)就变成了(c1 c2).(c1 c2)相当于下面的调用

(define (c1 c2)
    (let ((yin (foox c2)));输出@
        (let ((yang (fooy (call/cc bar))));输出*
    (yin yang)))
)

用同样的手段,将(let ((yang (fooy (call/cc bar))))简化成(let ((yang c3))

(define (c1 c2)
    (let ((yin c2))
        (let ((yang c3))
    (yin yang)))
)

所以最后的(yin yang)变成了(c2 c3),而(c2 c3)又相当于下面的函数调用:

(define (c2 c3)
    (let ((yin c1))
    (let ((yang (fooy c3)));输出*
    (yin yang)))
)

继续简化:(yin yang)变成(c1 c3),(c1 c3)又等价于:

(define (c1 c3)
    (let ((yin (foox c3)));输出@
        (let ((yang (fooy (call/cc bar))));输出*
    (yin yang)))
)

将(let ((yang (fooy (call/cc bar))))用(let ((yang c4))替代(yin yang)变成了(c3 c4)

(define (c3 c4)
    (let ((yin c2))
        (let ((yang (fooy c4)));输出*
    (yin yang)))
)

简化后(yin yang)变成(c2 c4),我们又回到这一步

(define (c2 c4)
    (let ((yin c1))
    (let ((yang (fooy c4)));输出*
    (yin yang)))
)

(yin yang)变成(c1 c4)

现在看下至今为止的输出:@*@**@***

好了,人肉scheme解释器的过程到此结束,因为这个程序会无休止的运行下去,所以人肉分析也是无休止的.

经过上述分析之后,相信对阴阳迷题和continuation又了更深刻的理解.

posted @ 2013-06-04 12:48  sniperHW  阅读(834)  评论(1编辑  收藏  举报