[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Simple macro question
From: |
Stefan Monnier |
Subject: |
Re: Simple macro question |
Date: |
Sun, 02 May 2021 21:46:30 -0400 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) |
> (defvar test-commands-list '(A B C)
> "List of replaced functions.")
> (defmacro test-def ()
> "Doc def."
> `(eval-and-compile ,@(mapcar (lambda (com) nil) test-commands-list)))
> (test-def)
[...]
> Symbol’s value as variable is void: test-commands-list
macro-expansion takes place during compilation. During compilation, the
code is mostly translated, not evaluated, but macros are expanded.
So your `(test-def)` macro call is expanded which evaluates the code
inside `test-def` whereas the `(defvar ...)` code is not evaluated (it's
only translated into byte-code) and hence the var is not defined: it
will only be defined much later when the resulting byte-code is run.
One way to work around it is to place the `defvar` within an
`eval-and-compile`.
> (defmacro test-def (commands-list)
> ...
>
> (test-def test-commands-list)
>
> In this second case I get: wrong arguments sequencep test-commands-list
> Is this intended?
Yes: the argument to macros are the actual sexp written in the macro
call, not the result of their evaluation. So your argument
`commands-list` will hold the symbol `test-commands-list` rather than
the list you were hoping to get. You could use `symbol-value` to get
the content of that symbol as a variable, but then you'd be back to the
previous problem because the `defvar` has not been evaluated yet.
Stefan