💾 Archived View for thrig.me › blog › 2022 › 11 › 18 › print-circle.gmi captured on 2024-05-26 at 15:28:43. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-11-14)
-=-=-=-=-=-=-
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