微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 Common Lisp REPL 在插入这个循环列表后会一直无限运行?

如何解决为什么 Common Lisp REPL 在插入这个循环列表后会一直无限运行?

我使用的是 Common Lisp、SBCL 和 Slime。我是 Common Lisp 的新手。

显然,这是 Common Lisp 中的循环列表:

#1=('a 'b 'c . #1#)

这将提供一个无限的 'a 'b 'c 'a 'b 'c 'a...

当我把它放在 REPL 上时,它会一直运行:

CL-USER> #1=('a 'b 'c . #1#)

为什么会这样?为什么 REPL 不返回它收到的“对象”?

如果我请求列表的下一个元素,我可以理解无限行为。但是,我向 REPL 询问了对象本身。

我期待与正确列表或点列表相同的行为:

CL-USER> (list 'a 'b 'c)
(A B C)

CL-USER> (cons 'a  (cons 'b 'c))
(A B . C)

解决方法

想一想打印这样的对象涉及什么:一台普通的打印机需要多长时间来打印它以及输出有多大?

好吧,CL 可以让您解决这个问题:有许多打印机控制变量,其中最直接有用的可能是 *print-circle*。您可以将此设置为 true 以在打印机中启用圆形检测。如果您这样做,您可能还会意识到为什么默认情况下它是 nil

,

如果我要求列表的下一个元素,我可以理解无限行为。

为什么?下一个元素不是具有无限计算时间的操作。它只是获取下一个元素,这只是一个简单的操作。它只是循环列表中的下一个元素。

无限是在循环中请求下一个元素,检查列表的末尾。

(cdr list)

对比

(dolist (e list)
  ...)

可能打印机(打印结果的读取评估打印循环的一部分)在想要打印无限列表的元素时会做类似的事情。 TFB 提到需要特殊检查来检测循环性以保持计算有界。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。