Reputation: 115
I've been playing around with circular list in Common-lisp (SBCL) and encountered the following problem when trying to call REDUCE
on such a list.
First, we create a list:
CL-USER> (defvar *foo* (list 1 1 1 1))
*foo*
Of course, now we can do
CL-USER> (reduce #'+ *foo*)
4
or
CL-USER> (reduce #'+ *foo* :end 3)
3
However, if we create a circular list:
CL-USER> (setf *print-circle* t)
CL-USER> (setf (cdr (last *foo*)) *foo*)
CL-USER> *foo*
#1=(1 1 1 1 . #1#)
Obviously (reduce #'+ *foo*)
now never returns.
But when I tried
CL-USER> (reduce #'+ *foo* :end 3)
...
I also got an infinite loop.
Why is that so? Is there any way to work around this without explicitly using
loop construct such as LOOP
or DO
? I'm working with SBCL, but tried this with other implementations (CLISP, ECL), they all have the same problem.
Upvotes: 3
Views: 291
Reputation: 60014
I agree that the behavior you observe can give one a start - after all, why not process the first 3 elements of the circular list?
Let us read the ANSI Common Lisp standard:
type-error
if sequence is not a proper sequence. Should be prepared to signal an error:
So,
3
is conforming as wellPersonally, I think that interactive code should be viewed as safe, so this is a bug. YMMV.
Upvotes: 5