Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Common LISP: convert (unknown) struct object to plist?

Tags:

common-lisp

(defstruct (mydate (:constructor make-mydate (year month day)))
  (year 1970)
  (month 1)
  (day 1))

 (defvar *date1* (make-mydate 1992 1 1))

The problem is more general, but say I would like to convert an object like date1 to a "document" I can persist to a database (e.g. mongoDB, using package cl-mongo). So I write

(defun mydate->document (mydate)
   (cl-mongo:$ (cl-mongo:$ "year" (mydate-year mydate))
               (cl-mongo:$ "month" (mydate-month mydate))
               (cl-mongo:$ "day" (mydate-day mydate))))

REPL--> (mydate->doc *date1*)
kv-container : #(#S(CL-MONGO::PAIR :KEY year :VALUE 1992)
                 #S(CL-MONGO::PAIR :KEY month :VALUE 1)
                 #S(CL-MONGO::PAIR :KEY day :VALUE 1))

But could I, instead of having to write down all fields of my struct, obtained their names and values programmatically? After all, my lisp runtime can do that:

REPL--> (describe *date1*)
#S(MYDATE :YEAR 1992 :MONTH 1 :DAY 1)
  [structure-object]

Slots with :INSTANCE allocation:
YEAR   = 1992
MONTH  = 1
DAY    = 1

On the other hand, I did not find anything relevant in any book, and I noticed that the library cl-json cannot convert structs to JSON format (even though it does convert lists and CLOS objects). I guess that if there was a function to convert a struct to a plist, the problem would be solved.

like image 967
engineerX Avatar asked May 07 '26 13:05

engineerX


1 Answers

There is no portable way.

Implementations do it differently. Probably most have a way to access the names of the slots. It's not clear to me why such functionality is missing from the standard.

LispWorks for example has:

(structure:structure-class-slot-names (find-class 'some-structure-class))

Maybe there is already a compatibility library somewhere. It would make sense to use the Meta-Object Protocol functionality for CLOS also for structure classes.

SBCL:

* (sb-mop:class-slots (find-class 'foo))

(#<SB-PCL::STRUCTURE-EFFECTIVE-SLOT-DEFINITION A>
 #<SB-PCL::STRUCTURE-EFFECTIVE-SLOT-DEFINITION B>)

* (mapcar 'sb-mop:slot-definition-name *)

(A B)
like image 67
Rainer Joswig Avatar answered May 11 '26 15:05

Rainer Joswig



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!