Macros Lisp-将不带引号的列表传递给宏

Macros Lisp-将不带引号的列表传递给宏,macros,lisp,common-lisp,clos,Macros,Lisp,Common Lisp,Clos,我目前正在Lisp中试用宏,我想编写一个宏,它可以处理以下语法: (my-macro (args1) (args2)) 宏应该包含两个列表,然后可以在我的宏中使用它们进行进一步处理。然而,问题在于,这些列表是不带引号的,以模仿一些真正的Lisp/CLOS函数的语法。这可能吗 当前,我在尝试执行类似操作时出现以下错误: Undefined function ARGS1 called with arguments (). 提前谢谢 我认为你需要展示你所做的努力。下面是一个(愚蠢的)宏的示例,它的

我目前正在Lisp中试用宏,我想编写一个宏,它可以处理以下语法:

(my-macro (args1) (args2))
宏应该包含两个列表,然后可以在我的宏中使用它们进行进一步处理。然而,问题在于,这些列表是不带引号的,以模仿一些真正的Lisp/CLOS函数的语法。这可能吗

当前,我在尝试执行类似操作时出现以下错误:

Undefined function ARGS1 called with arguments ().

提前谢谢

我认为你需要展示你所做的努力。下面是一个(愚蠢的)宏的示例,它的参数模式与您的非常相似:

(defmacro stupid-let ((&rest vars) (&rest values) &body forms)
  ;; Like LET but with a terrible syntax
  (unless (= (length vars) (length values))
    (error "need exactly one value for each variable"))
  (unless (every #'symbolp vars)
    (error "not every variable is a symbol"))
  `(let ,(mapcar #'list vars values) ,@forms))
然后

上述宏取决于
defmacro
的arglist解构,但您不必这样做:

(defun proper-list-p (l)
  ;; elaborate version with an occurs check, quadratic.
  (labels ((plp (tail tails)
             (if (member tail tails)
                 nil
               (typecase tail
                 (null t)
                 (cons (plp (rest tail) (cons tail tails)))
                 (t nil)))))
    (plp l '())))

(defmacro stupid-let (vars values &body forms)
  ;; Like LET but with a terrible syntax
  (unless (and (proper-list-p vars) (proper-list-p values))
    (error "need lists of variables and values"))
  (unless (= (length vars) (length values))
    (error "need exactly one value for each variable"))
  (unless (every #'symbolp vars)
    (error "not every variable is a symbol"))
  `(let ,(mapcar #'list vars values) ,@forms))
作为一个稍微有用的示例,这里有一个宏,有点像CLOS
带插槽的宏
/
带存取器的宏
宏:

(defmacro with-mindless-accessors ((&rest accessor-specifications) thing
                                   &body forms)
  "Use SYMBOL-MACROLET to define mindless accessors for THING.

Each accessor specification is either a symbol which names the symbol
macro and the accessor, or a list (macroname accessorname) which binds
macroname to a symbol macro which calls accessornam.  THING is
evaluated once only."
  (multiple-value-bind (accessors functions)
      (loop for accessor-specification in accessor-specifications
            if (symbolp accessor-specification)
            collect accessor-specification into acs
            and collect accessor-specification into fns
            else if (and (proper-list-p accessor-specification)
                         (= (length accessor-specification) 2)
                         (every #'symbolp accessor-specification))
            collect (first accessor-specification) into acs
            and collect (second accessor-specification) into fns
            else do (error "bad accessor specification ~A" accessor-specification)
            end
            finally (return (values acs fns)))
    (let ((thingn (make-symbol "THING")))
    `(let ((,thingn ,thing))
       (symbol-macrolet ,(loop for accessor in accessors
                               for function in functions
                               collect `(,accessor (,function ,thingn)))
         ,@forms)))))
现在我们可以编写一些无用的代码:

> (with-mindless-accessors (car cdr) (cons 1 2)
    (setf cdr 3)
    (+ car cdr))
4
这是:

> (let ((l (list 1 2)))
    (with-mindless-accessors (second) l
      (setf second 4)
      l))
(1 4)

你可能会发现在实验之前阅读它更有用。代码在哪里?宏在宏扩展时从一种语法转换到另一种语法。它不在乎引用什么,您可以在转换中将输入转换为引用。
> (let ((l (list 1 2)))
    (with-mindless-accessors (second) l
      (setf second 4)
      l))
(1 4)