我在处理 CL 中的一些嵌套反引号时遇到了一些麻烦。我正在尝试创建一个宏 define-access
,它采用两个参数,F
和 A
。 define-access
应该为符号 F
定义一个函数和 setf 扩展,其作用就像 A
的相应函数和 setf。目前代码如下。
(defmacro define-access (F A)
(let ((X (gensym))
(Y (gensym)))
`(progn
(defun ,F (,X)
(,A ,X))
(defsetf ,F (,X) (,Y)
`(setf (,A ,,X) ,,Y)))))
问题出现在底部,带有嵌套的反引号。
define-access
的预期行为如下。
(define-access fname car)
=> (progn (defun fname (x) (car x))
(defsetf fname (x) (y) `(setf (first ,x) ,y)))
但是现在,根据 macroexpand-1
,我得到了以下内容(为了理智而添加了换行符)。
(PROGN (DEFUN FNAME (#:G22490) (CAR #:G22490))
(DEFSETF FNAME (#:G22490) (#:G22491)
(LIST 'SETF (LIST A #:G22490) #:G22491)))
我对反引号运算符有什么不理解的,或者我应该如何处理这类问题?
在嵌套反引号中的 A
之前需要另一个逗号,因此它会扩展到外部反引号之外的变量值。然后需要引用它以防止将其评估为变量。于是就变成了,',A
(defmacro define-access (F A)
(let ((X (gensym))
(Y (gensym)))
`(progn
(defun ,F (,X)
(,A ,X))
(defsetf ,F (,X) (,Y)
`(setf (,',A ,,X) ,,Y)))))
DEMO
我是一名优秀的程序员,十分优秀!