我是一个普通的lisp新手。我对以下宏有一些麻烦:
我有什么:
假设我有一个全局变量*JAN2018*
,它是:
(:NAME "*JAN2018*" :MONTH "Jan" :YEAR 2018 :EXPENSES (:VALUE NIL :TAGS NIL))
如果我跑
(setf (getf *jan2018* :expenses) '(:value 23 :tags '("a" "b")))
我选择*jan2018*
(:NAME "*JAN2018*" :MONTH "Jan" :YEAR 2018 :EXPENSES
(:VALUE 23 :TAGS '("a" "b")))
问题:
现在我有了宏:
(defmacro test (sym)
(setf `(getf ,sym :expenses) '(:value 23 :tags '("a" "b"))))
如果我跑
(test *jan2018*)
我得到(使用SBCL)
*The function (COMMON-LISP:SETF COMMON-LISP:LIST*) is undefined.
[Condition of type UNDEFINED-FUNCTION]*
我要做的是传递一个符号并更新其中一个字段。为什么我收到此错误,如何继续更新列表?
答案 0 :(得分:3)
要调试宏,请使用macroexpand
:
(macroexpand-1 '(test *jan2018*))
*** - FUNCTION: undefined function (SETF CONS)
这是因为您尝试在宏扩展时执行(setf (list 'getf *jan2018* ...) ...)
。
我担心我无法提供任何具体的建议,因为目前尚不清楚你究竟要通过宏来完成什么。
您使用的设施不正确。 使用函数而不是宏:
(defun test (sym)
(setf (getf sym :expenses) '(:value 23 :tags '("a" "b"))))