我在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)))
我不了解反引号运算符,或者我该如何处理这类问题?
答案 0 :(得分:3)
在嵌套反引号中,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)))))