【问题标题】:Why the Common Lisp REPL keeps infinitely running after the insertion of this circular list?为什么 Common Lisp REPL 在插入这个循环列表后会无限运行?
【发布时间】:2021-08-05 16:04:45
【问题描述】:

我正在使用 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)

【问题讨论】:

  • 另外请注意,通常不需要在引用列表中引用符号。

标签: common-lisp read-eval-print-loop infinite circular-list


【解决方案1】:

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

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

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

(cdr list)

对比

(dolist (e list)
  ...)

printer(Read Eval Print Loop 中打印结果的部分)可能会在它想要打印无限列表的元素时执行类似的操作。 TFB 提到需要特殊检查来检测循环性以保持计算有界。

【讨论】:

    【解决方案2】:

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

    嗯,CL 可以让你驯服这个:有许多打印机控制变量,其中最直接有用的可能是*print-circle*。您可以将其设置为 true 以在打印机中启用圆形检测。如果你这样做了,你也可能会意识到为什么默认是nil

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-28
      • 2021-09-12
      相关资源
      最近更新 更多