我一直在使用Common-lisp(SBCL)中的循环列表,并在尝试在这样的列表上调用REDUCE
时遇到以下问题。
首先,我们创建一个列表:
CL-USER> (defvar *foo* (list 1 1 1 1))
*foo*
当然,现在我们可以做到
CL-USER> (reduce #'+ *foo*)
4
或
CL-USER> (reduce #'+ *foo* :end 3)
3
但是,如果我们创建一个循环列表:
CL-USER> (setf *print-circle* t)
CL-USER> (setf (cdr (last *foo*)) *foo*)
CL-USER> *foo*
#1=(1 1 1 1 . #1#)
显然(reduce #'+ *foo*)
现在永远不会回来了。
但是当我尝试
时 CL-USER> (reduce #'+ *foo* :end 3)
...
我也有一个无限循环。
为什么会这样?有没有办法在没有明确使用的情况下解决这个问题
循环结构,如LOOP
或DO
?我正在使用SBCL,但尝试使用其他实现(CLISP,ECL),它们都有同样的问题。
答案 0 :(得分:5)
我同意你观察到的行为可以给一个开始 - 毕竟,为什么不处理循环列表的前3个元素?
让我们阅读ANSI Common Lisp标准:
type-error
类型的错误信号。 Should be prepared to signal an error:
所以,
3
也符合就个人而言,我认为交互式代码应该被视为安全,因此这是一个错误。 YMMV。