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.