-- Leo's gemini proxy

-- Connecting to thrig.me:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

*print-circle*


LISP structures may be circular, for example when a graph creates loops because it is one of them cyclical graphs.


    ; circle1.lisp
    (defstruct node (next nil :type (or null node)))
    (let* ((aaa (make-node))
           (bbb (make-node :next aaa)))
      (setf (node-next aaa) bbb)
      (format t "~a~&" n))

Printing this infinite graph does pose a problem.


    $ sbcl --script circle1.lisp >out
    fatal error encountered in SBCL pid 775 pthread 0x28de7cf80:
    Control stack exhausted, fault: 0x2190b7ff0, PC: 0x21af0f06

    $ head -3 out
    #S(NODE
       :NEXT #S(NODE
                :NEXT #S(NODE

Luckily OpenBSD sets various limits low so it does not take long for the process to keel over and die.


Now, some LISP folks will insist that making *print-circle* true will prevent the infinite loops. By this they probably mean to run


    (setf *print-circle* t)

somewhere to mutate the state of the global. Now if one actually uses emacs and some LISP image, and one remembers to keep that flag on, that may be the end of the story.


But what does this code do?


    ; circle2.lisp
    (defstruct node (next nil :type (or null node)))

    (defun node-bilink (aaa bbb)
      (setf (node-next aaa) bbb)
      (setf (node-next bbb) aaa)
      aaa)

    (defun new-graph ()
      (node-bilink (make-node) (make-node)))

    (let ((x (new-graph)))
      (let ((*print-circle* t))
        x))

Could it depend on how you run it?


    $ sbcl --script circle2.lisp
    $

And then this should be the same... right?


    $ sbcl < circle2.lisp

Anyways, I ignored the #clschool advice, and put in a custom print function for the node struct that does not print any of the node links. (The #lispgames folks were more aware of the need to perhaps not rely too much on *print-circle*.)


tags #lisp

-- Response ended

-- Page fetched on Tue May 21 09:54:28 2024