在 Lisp 中打印 defstruct

发布于 2025-01-06 21:28:51 字数 803 浏览 1 评论 0原文

我在 Lisp 中定义了一个非常简单的数据结构:

;;Data structure for a person

(defstruct person
  (name nil)
  (age 0)
  (siblings nil :type list))   ;; Siblings is a list of person objects

然后我继续实例化一些人员对象:

(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-b person-a))

然后我如何打印有关对象的信息我已经实例化并修改了吗?我已经研究了关于打印对象和打印函数的 defstruct 选项,但我不知道如何正确打印我的对象。使用类似以下内容:

(print person-a)

将我的 ACL 解释器发送到无限循环。

I have a very simple data structure that I have defined in Lisp:

;;Data structure for a person

(defstruct person
  (name nil)
  (age 0)
  (siblings nil :type list))   ;; Siblings is a list of person objects

I then procede to instantiate a few person objects:

(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))

I then relate the siblings (assume they are all siblings of each other):

(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-b person-a))

How can I then print information about the objects that i've instantiated and modified? I have looked into the options of a defstruct with regard to print-object and print-function but I cannot figure out how to properly print my objects. Using something like:

(print person-a)

sends my ACL interpreter into an infinite loop.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

趴在窗边数星星i 2025-01-13 21:28:51

Common Lisp 有一个控制递归结构打印的变量: *打印圆*。在你的 Lisp 中,默认情况下它可能是 false (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,然后我收到堆栈溢出错误(sbcl 中的SB-KERNEL::CONTROL-STACK-EXHAUSTED)。

HTH,

凯尔

Common lisp has a variable that controls the printing of recursive structures: *print-circle*. In your Lisp it may be false (nil) by default (as it is in SBCL and clisp - I'm not familiar with ACL), which is probably causing the infinite loop. If you set it to t, your structures should print:

(setf *print-circle* t)

I tested this with the following file:

(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)

Here is a transcript from running that code:

> 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)

If I leave *print-circle* nil, then I get a stack overflow error (SB-KERNEL::CONTROL-STACK-EXHAUSTED in sbcl).

HTH,

Kyle

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文