Common lisp имеет переменную, которая управляет печатью рекурсивных структур: *print-circle*
. В вашем Лиспе он может быть ложным (nil
) по умолчанию (как в SBCL и clisp - я не знаком с ACL), что, вероятно, вызывает бесконечный цикл. Если вы установите значение t
, ваши структуры должны напечатать:
(setf *print-circle* t)
Я проверил это с помощью следующего файла:
(defstruct person
(name nil)
(age 0)
(siblings nil :type list))
(setf person-a (make-person :name 'Tim :age 23))
(setf person-b (make-person :name 'Sally :age 21))
(setf person-c (make-person :name 'Louis :age 24))
(setf (person-siblings person-a) (list person-b person-c))
(setf (person-siblings person-b) (list person-a person-c))
(setf (person-siblings person-c) (list person-a person-b))
(setf *print-circle* t)
(format t "~a~&" person-a)
(format t "~a~&" person-b)
(format t "~a~&" person-c)
(print person-a)
(print person-b)
(print person-c)
Вот расшифровка стенограммы запуска этого кода:
> sbcl
This is SBCL 1.0.55, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (load "defstruct.lisp")
#1=#S(PERSON
:NAME TIM
:AGE 23
:SIBLINGS (#2=#S(PERSON
:NAME SALLY
:AGE 21
:SIBLINGS (#1#
#3=#S(PERSON
:NAME LOUIS
:AGE 24
:SIBLINGS (#1# #2#))))
#3#))
#1=#S(PERSON
:NAME SALLY
:AGE 21
:SIBLINGS (#2=#S(PERSON
:NAME TIM
:AGE 23
:SIBLINGS (#1#
#3=#S(PERSON
:NAME LOUIS
:AGE 24
:SIBLINGS (#2# #1#))))
#3#))
#1=#S(PERSON
:NAME LOUIS
:AGE 24
:SIBLINGS (#2=#S(PERSON
:NAME TIM
:AGE 23
:SIBLINGS (#3=#S(PERSON
:NAME SALLY
:AGE 21
:SIBLINGS (#2# #1#))
#1#))
#3#))
#1=#S(PERSON
:NAME TIM
:AGE 23
:SIBLINGS (#2=#S(PERSON
:NAME SALLY
:AGE 21
:SIBLINGS (#1#
#3=#S(PERSON
:NAME LOUIS
:AGE 24
:SIBLINGS (#1# #2#))))
#3#))
#1=#S(PERSON
:NAME SALLY
:AGE 21
:SIBLINGS (#2=#S(PERSON
:NAME TIM
:AGE 23
:SIBLINGS (#1#
#3=#S(PERSON
:NAME LOUIS
:AGE 24
:SIBLINGS (#2# #1#))))
#3#))
#1=#S(PERSON
:NAME LOUIS
:AGE 24
:SIBLINGS (#2=#S(PERSON
:NAME TIM
:AGE 23
:SIBLINGS (#3=#S(PERSON
:NAME SALLY
:AGE 21
:SIBLINGS (#2# #1#))
#1#))
#3#))
T
* (sb-ext:quit)
Если я оставлю *print-circle*
nil
, то получу ошибку переполнения стека (SB-KERNEL::CONTROL-STACK-EXHAUSTED
в sbcl).
НТН,
Кайл