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.
(reduce #'+ *foo* :end 3)produces3, while(reduce #'+ *foo*)signal a[Condition of type CCL::IMPROPER-LIST]. - Renzo