如何解决为什么 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 举报,一经查实,本站将立刻删除。