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

Why the Common Lisp REPL keeps infinitely running after the insertion of this circular list?

我正在使用 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 没有 return 它收到的“对象”?

如果我要求列表的下一个元素,我可以理解无限行为。但是,我向 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

I can understand an infinite behavior if I was asking for the next element of the list.

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

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

(cdr list)

对比

(dolist (e list)
  ...)

printer(打印结果的 Read Eval Print Loop 部分)可能会在想要打印无限列表的元素时做类似的事情。 TFB 提到需要特殊检查来检测循环以保持计算范围。