代码之家  ›  专栏  ›  技术社区  ›  Makketronix

在common lisp中获取“common lisp:setf common lisp:list*未定义”

  •  0
  • Makketronix  · 技术社区  · 7 年前

    我是一个普通的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*)
    

    I get(使用SBCL)

    *The function (COMMON-LISP:SETF COMMON-LISP:LIST*) is undefined.
       [Condition of type UNDEFINED-FUNCTION]*
    

    我想做的是传递一个符号并更新它的一个字段。为什么会出现此错误,以及如何继续更新列表?

    1 回复  |  直到 7 年前
        1
  •  3
  •   sds Niraj Rajbhandari    7 年前

    你眼前的问题

    要调试宏,请使用 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"))))