Common lisp 使用结构作为宏的属性列表

Common lisp 使用结构作为宏的属性列表,common-lisp,Common Lisp,我有一个带有:name和:value的结构,我想将其用作宏的参数。但我不知道该怎么告诉lisp 我可以这样写电话 (sxql:yield (sxql:set= :name "a" :value 1)) “集名称=?,值=?” (“a”1) 但是我想使用一个已经存在的结构 (defstruct my-struct name value) (setq x (make-my-struct :name "a" :value 1)) ; #S(MY-STRUCT

我有一个带有
:name
:value
的结构,我想将其用作宏的参数。但我不知道该怎么告诉lisp

我可以这样写电话

(sxql:yield (sxql:set= :name "a" :value 1))
“集名称=?,值=?”

(“a”1)

但是我想使用一个已经存在的结构

(defstruct my-struct name value)
(setq x (make-my-struct :name "a" :value 1))
; #S(MY-STRUCT :NAME "a" :VALUE 1)
使用来自 我做了

(defun struct-plist (x)
  "make struct X into a property list. ugly kludge"
  (let* ((slots (sb-mop:class-slots (class-of x)))
     (names (mapcar 'sb-mop:slot-definition-name slots)))
    (alexandria:flatten
     (mapcar (lambda (n) (list (intern (string n) "KEYWORD")
                   (slot-value x n)))
         names))))
我天真的尝试是错误的

(sxql:set= p) ; error in FORMAT: No more argument SET ~{~A = ~A~^, ~}
(funcall 'sxql:set= p) ; SXQL:SET= is a macro, not a function.
(macroexpand (sxql:set= p)) ; error in FORMAT ...
我想这是一个简单/基本的lisp编程问题。但我不知道如何提问(或寻找答案)。我也希望有一个比我目前偶然发现的更好的结构主义故事


编辑:如果这真的是xy问题。我使用了
flydata:defmodel
来创建结构,我想插入到使用相同模型的数据库中。

这肯定是一个xy问题:不幸的是,我不太了解y(flydata?),无法回答y部分

然而,这就是为什么你所尝试的方法无法奏效的原因。在编译的文件中考虑此代码:

(defstruct mine name value)

...

(sxql:set= <anything derived from mine>)
所以现在

(define-mindless-structure mine
  name value)
将扩展到
(defstruct mine name value)
,并在宏扩展时将有关此结构的一些信息隐藏在
*结构信息*

现在我不再真正理解您需要做什么,因为我不知道
sxql:set=
要做什么,但可能是这样的:

(defmacro mindless-set= ((s o))
  (let ((info (assoc s *structure-information*))
        (ov (make-symbol "O")))
    (unless info
      (error "no information for ~A" s))
    `(let ((,ov ,o))
       (sxql:set= ,@(loop for (slot initarg accessor) in (cdr info)
                          ;; the compiler will whine about slot annoyingly
                          collect initarg
                          collect `(,accessor ,ov))))))
因此,使用此宏,假设在展开宏时已看到
mine
表单的合适
define mindless结构
,则

(mindless-set= (mine it))
将扩展到

(let ((#:o it))
  (set= :name (mine-name #:o) :value (mine-value #:o)))
但是,正如我所说的,我不确定你真正想要的扩张是什么



最后,在考虑使用上述任何功能之前,有必要四处看看是否有提供编译/宏扩展时功能的可移植性库:很可能会有这样的库,因为我没有跟上进度。

谢谢您的详细回答!教导式的定义无意识结构是超级的helpful@Will当前位置是的,“说教式”是我应该使用的术语:我很高兴你意识到了这一点。这不是工业实力,但我希望能有所帮助。
(mindless-set= (mine it))
(let ((#:o it))
  (set= :name (mine-name #:o) :value (mine-value #:o)))