Here's my macro, what it is supposed to do is to wrap a body
in let
with bindings from vars-alist
(defmacro with-vars-alist (vars-alist &rest body)
`(let (,@(mapcar (lambda (cell) (list (car cell) (cdr cell))) vars-alist))
,@body))
When I am looking at what it expands to using following code
(defvar my-vars-alist '((var1 . "var1")
(var2 . "var2")))
(macroexpand-1 (with-vars-alist my-vars-alist `(concat ,var1 ,var2)))
I get an error cons: Wrong type argument: sequencep, my-vars-alist
However checking it (sequencep my-vars-alist)
return t
.
The error is probably has some simple solution, but I am just unable to find it.
Remember that arguments to macros are un-evaluated, which means that when you pass my-vars-alist
as an argument, it is passed verbatim as the symbol my-vars-alist
.
Therefore during the macro expansion, vars-alist
evaluates to the symbol my-vars-alist
rather than the list ((var1 . "var1") (var2 . "var2"))
.
So the error isn't complaining that the variable my-vars-alist
doesn't contain a sequence as its value, but rather that the symbol my-vars-alist
is not itself a sequence (which is correct -- it's a symbol).
checking it
(sequencep my-vars-alist)
returnt
.
Which is also correct, as there my-vars-alist
is evaluated as a variable to its value of ((var1 . "var1") (var2 . "var2"))
So you need to eval
that argument. e.g.:
,@(mapcar (lambda (cell) (list (car cell) (cdr cell)))
(eval vars-alist))
As vars-alist
is already being evaluated to the symbol my-vars-alist
, this change means that we are passing that symbol my-vars-alist
to eval
, which evaluates it as a variable to obtain the list needed for mapcar
.
You probably also wanted to quote the form you pass to macroexpand-1
(or use M-x pp-macroexpand-last-sexp
).