Reputation: 70277
I'm having some trouble with some nested backquotes in CL. I'm trying to create a macro define-access
that takes two parameters, F
and A
. define-access
should define a function and setf expansion for symbol F
that acts just like the respective function and setf for A
. The current code is as follows.
(defmacro define-access (F A)
(let ((X (gensym))
(Y (gensym)))
`(progn
(defun ,F (,X)
(,A ,X))
(defsetf ,F (,X) (,Y)
`(setf (,A ,,X) ,,Y)))))
The problem arises at the bottom, with the nested backquote.
The desired behavior of define-access
is as follows.
(define-access fname car)
=> (progn (defun fname (x) (car x))
(defsetf fname (x) (y) `(setf (first ,x) ,y)))
But right now, according to macroexpand-1
, I'm getting the following (line breaks added for sanity).
(PROGN (DEFUN FNAME (#:G22490) (CAR #:G22490))
(DEFSETF FNAME (#:G22490) (#:G22491)
(LIST 'SETF (LIST A #:G22490) #:G22491)))
What am I not understanding about the backquote operator, or how should I approach this sort of problem?
Upvotes: 2
Views: 106
Reputation: 781058
You need another comma before A
in the nested backquote, so it expands to the value of the variable outside the outside the outer backquote. And then it needs to be quoted to keep from evaluating that as a variable. So it becomes ,',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)))))
Upvotes: 3