【发布时间】:2015-04-02 11:26:04
【问题描述】:
例如,我想从 lambda 列表中获取所有变量来定义宏:
(defmacro my-defun (name lambda-list &body body &aux (fname (gensym)))
`(progn
(defun ,fname ,(all-vars lambda-list)
,@body)
(defun ,name ,lambda-list
(,fname ,@(all-vars lambda-list)))))
是否有一些函数可以使用 lambda 列表更轻松地完成此操作或其他事情,或者没有比编写这样的函数更简单的方法:
(defun all-vars (lambda-list)
(mapcar (lambda (cons) (if (consp cons) (car cons) cons))
(remove-if (lambda (symbol) (and (symbolp symbol)
(char= (char (symbol-name symbol) 0) #\&)))
lambda-list)))
【问题讨论】:
-
不是检查变量的第一个字符是否为#\&,而是检查符号是否在lambda-list-keywords中。
-
即便如此,您也必须注意正确的语法和其他细微之处:
lambda-list-keywords的符号比函数的 lambda 列表中允许的符号多,顺序很重要,&optional和 @987654326 @ 参数可能是一个缺点,它们在语法上有所不同,&aux不是真正的参数,等等。 -
@PauloMadeira 绝对正确,尤其是关于 &aux 变量。但是,由于宏扩展包含
(defun ,name ,lambda-list ...),因此实现必须检查 lambda 列表的正确性,因此在这种特殊情况中检查并不那么重要。
标签: lambda macros common-lisp