Search code examples
common-lispread-eval-print-loopinfinitecircular-list

Why the Common Lisp REPL keeps infinitely running after the insertion of this circular list?


I am using Common Lisp, SBCL and Slime. I am new to Common Lisp.

Apparently, this is a circular list in Common Lisp:

#1=('a 'b 'c . #1#)

This would provide an infinite 'a 'b 'c 'a 'b 'c 'a...

When I put this on the REPL it keeps running forever:

CL-USER> #1=('a 'b 'c . #1#)

Why does that happen? Why the REPL does not return the "object" it received?

I can understand an infinite behavior if I was asking for the next element of the list. However, I asked the REPL about the object itself.

I was expecting the same behavior that happens with proper lists or dotted lists:

CL-USER> (list 'a 'b 'c)
(A B C)

CL-USER> (cons 'a  (cons 'b 'c))
(A B . C)

Solution

  • I can understand an infinite behavior if I was asking for the next element of the list.

    Why? The next element is not an operation with infinite compute time. It's just getting the next element, which is only a simple operation. It's just the next element in a circular list.

    What's infinite is when one asks for the next element in a loop, checking for the end of the list.

    (cdr list)
    

    vs.

    (dolist (e list)
      ...)
    

    Probably the printer (the part of the Read Eval Print Loop which prints the result) will do something similar when it wants to print the elements of an infinite list. TFB mentioned that one needs special checks to detect circularity to keep the computation bounded.