David Madore 的 Scheme 迷题解释

发布于 2022-08-06 22:51:52 字数 1670 浏览 33 评论 9

就是传说中的阴阳迷题,我把代码改了一下,本质是一样的。

  1. (define (id x) x)
  2. (define (f x) (display "O")  x)
  3. (define (g x) (display "-")  x)
  4. ((f (call/cc id)) (g (call/cc id)))

复制代码

这个程序的输出是什么? 把代码执行一下就知道了,问题是为什么有这样的输出?

这个问题有点难分析,我尽量把关键点讲清。但前提是你必须对 continuation 有充分的理解。

这个问题的难点不在 continuation,而在 continuation 的折腾。

这里有三个函数,id 直接把参数返回,是一个单位映射。f, g 也直接把参数返回,但返回前有一个输出语句。所以 f, g 是带副作用的单位映射。

从代码上看,有两处 call/cc。而分析一下代码的执行流程,就会发现,前一个 call/cc 只执行了一次,产生了一个 continuation 对象。当然,这个对象会多次返回。而后一个 call/cc 则被反复调用,产生出一系列的 continuation 对象。

我们把第一个 call/cc 产生的 continuation 称为 c0,而由第二个 call/cc 产生的一系列 continuation 分别称为 c1, c2, c3, c4, .......

先忽略掉副作用,则 id, f, g 都是单位映射,它们的工作只不过是把 continuation 传来传去而已。

c0 先被制造出来,然后是 c1,之后 c0 作用在 c1 上,此时 c0 返回,得到 (f c1), 进一步得到 c1,这是个关键点,此时执行的是 (c1 (g (call/cc id)),c2 被产出,得到 (c1 c2)

按造这个方法分析下去,不难发现 call/cc 产出 ck 后,会作为 c(k-1) 的输入,得到 ( c(k-1), ck).

从 (c(k-1), ck) 出发,从 continuation 上看,跳转(或返回) 为 ck-> c(k-2)->c(k-2)-> ... -> c1 得到 (c0 (f ck))

此后 (f ck) -> (c0 ck) -> (f ck) -> ck,从而下一个 call/cc 被调用, c(k+1) 产生。

最后把副作用算上,continuation 转换序列为

c0 | c1 c0 | c2 c1 c0 | c3 c2 c1 c0 | ......

c0 返回后会打引一个 O;ci (i>0) 返回后会打印一个 - (本来想打印 | 的,不过为了引人一点 lazy 味道,我让它躺下,成为 -).

所以输出为

O-O--O---O----O-----O------O-------O--------O---------O----------O-----------O--- ...... ;; 还有很多,很多....

[ 本帖最后由 win_hate 于 2008-9-5 22:55 编辑 ]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

拧巴小姐 2022-08-17 09:29:43

原帖由 win_hate 于 2008-9-6 09:48 发表

DrScheme 在我这里从来没有正常工作过,恩,应该说从来没工作过。不知到是 64 位还是 SCIM 输入法的问题。症状为对输入没有反应,CPU 使用率飙升一段时间,之后仍然不能输入。

呃,我用 DrScheme 基本没碰到什么问题,不论是 Linux 还是 Mac OS X。就是在 Debian 上 DrScheme 4 二进制版本安装后有问题,不过从源码编译后就好了。至于说中文输入法,我没在 DrScheme 中用过。

左岸枫 2022-08-17 09:25:35

我在 MIT-Scheme 里面运行了,结果是这样的:

OO-OO-OO- ...

MIT-Scheme 中没有 call/cc 这样的函数,所以我:

  1. (define (call/cc) (call-with-current-continuation))

复制代码

Why

要走就滚别墨迹 2022-08-17 09:24:02

我放到 drscheme 里怎么运行不了啊

滿滿的愛 2022-08-17 07:44:25

原帖由 MMMIX 于 2008-9-6 08:22 发表

没用过 DrScheme 的集成开发环境吧?它的括号高亮相当有特色。

DrScheme 在我这里从来没有正常工作过,恩,应该说从来没工作过。不知到是 64 位还是 SCIM 输入法的问题。症状为对输入没有反应,CPU 使用率飙升一段时间,之后仍然不能输入。

3MIX 老大知道如何解决吗?

稀香 2022-08-16 23:43:52

原帖由 flw 于 2008-9-6 00:11 发表

我觉得数括号比较头疼。

没用过 DrScheme 的集成开发环境吧?它的括号高亮相当有特色。

猥琐帝 2022-08-16 21:37:22

原帖由 win_hate 于 2008-9-5 23:55 发表
要不你来学 scheme,我来学 Haskell,那样就不用翻来翻去了。

我觉得数括号比较头疼。

流年里的时光 2022-08-16 18:13:09

要不你来学 scheme,我来学 Haskell,那样就不用翻来翻去了。

你げ笑在眉眼 2022-08-14 04:30:07

看不懂,谁能给翻译成 Haskell?

蓝海 2022-08-11 02:47:29

也可以撇开细节,只说每个 ck 被造出来后,打印一个 -,之后返回 c(k-1),而我们知道从这个状态出发会打印 k-1 个 -,总共 k 个 -.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文