Fu
Simple is Beautiful!

scheme continuation之阴阳谜题

以下为阴阳谜题的 scheme 代码:

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

以上程序运行的结果为:

@*@**@***@****@*****@******
...

之所以会出现如此结果(循环渐增的打印星号),都是 scheme 中的 continuation 在作怪! 以下让我们来分析以下这个程序吧!

其中:

(call/cc (lambda (bar) bar))

此表达式返回当前的 continuation

(lambda (foo) (display "@") foo)

此表达式先是打印 "@" 字符,然后把 foo 参数作为函数的返回值返回

((lambda (foo) (display "@" foo))
     (call/cc (lambda (bar) bar)))

此表达式先是打印 "@" 字符,然后把当前的 continuation 作为函数返回值返回

环境1

let* 语句中,首先对 yinyang 变量依次赋值, yinyang 都被赋为一个 continuation, 两个 continuation 假设分别为 @CC*CC

yin=@CC       同时打印 @
yang=*CC      同时打印 *

运行 (yin yang),即为 (@CC *CC)

环境2

此时,由于 (@CC *CC) 表达式调用 @CC continuation 把 *CC 作为返回值返回 从而 yinyang 被重新赋值(两者仍都是一个 continuation):

yin=*CC         同时打印 @
yang=**CC       同时打印 *

之所以 yang 等于 **CC 而不是 *C,是因为 yang 被赋值前,yin 已被赋值为 *C, 其不同于 环境1 中的 yin环境1 中的 yin 被赋值为 @CC)。

运行 (yin yang),即为 (*CC **CC)

环境3

此时,由于 (*CC **CC) 表达式调用 *CC continuation 把 **CC 作为返回值返回, 在此要注意 *CC 所在的环境(yin 已被赋值为 @CCyang被赋值为 call/cc 函数的返回值,在此即为 **CC) 从而 yang 被重新赋值:

yin=@CC
yang=**CC      同时打印 *

运行 (yin yang),即为 (@CC **CC)

环境4

此时,由于 (@CC **CC) 表达式调用 @CC continuation 把 **CC 作为返回值返回, 从而 yinyang 被重新赋值:

yin=**CC        同时打印 @
yang=***CC      同时打印 *

之所以 yang 等于 ***CC,是因为 yang 被赋值前,yin 已被赋值为**C, 其不同于 环境1/环境2 中的 yin环境1 中的被赋值为 @CC环境2 中被赋值为 *CC

运行 (yin yang),即为 (**CC ***CC)

环境...,往复循环不止

scheme30
2010-11-25 13:38:00