I have a macro that needs to be expanded at every single instance of
its use compile-time. Is there a way I can specify this to be so
without going through the codebase and carefully wrapping each call
with eval-when-compile
?

- 6,861
- 16
- 85
2 Answers
All macros reachable by the byte-compiler are expanded during compilation. "Reachable" essentially means not being quoted.
The body of defun
s, defmacro
s, lambda
s, are all byte-compiled
when the source file that contains them is byte-compiled. So yes, any
macro inside them will be expanded, as long as they're not inside a
quote ('
). A very common mistake is to wrap lambda
s in a quote
and, in fact, that's why you should never quote your lambda
s.
This is one of the big advantages of macros, as long as they're well written, they have no impact on runtime performance. The other advantage is their power and versatility, of course. The disadvantage is that you're manipulating the syntax, not objects, so there's a lot of room for problems, some unexpected, others unavoidable.

- 22,878
- 6
- 78
- 163
As Malabarba has already explained, macros are expanded during byte compilation. If a file is not compiled, macros are expanded when the file is loaded (eager macro expansion).
Don't rely on this, though. It's very bad style. You generally can't expect that code which uses your macro is actually compiled, and you should generally run as little code as possible during compilation. Specifically, use macros scarcely and only if there is no other way. As a rule of thumb, use macros only for syntax, and never for semantics (or functionality).
Macros are a leaky abstraction. Their expansion is hard-coded into the target code at compilation time, and cannot be changed retrospectively. The target code subsequently depends on the specific implementation of the macro at the expansion time. Specifically, it depends on all internal API used in the macro body.
Consequently you cannot change any of this API, or anything the macro expansion relies upon, without breaking any code that was compiled against your macro.
The liberal use of macros for functionality paves the road to the dependency hell.
-
Very good points to be kept in mind when writing or using macros. – Sean Allred Dec 15 '14 at 21:37
-
"The liberal use of macros for functionality paves the road to the dependency hell." Until a week ago, package.el had a bug which completely broke package installation under perfectly legitimate macro dependency situations. – Malabarba Dec 15 '14 at 21:44
-
@Malabarba Care to provide details? – Dec 15 '14 at 21:50
-
@lunaryorn [Here you go](http://lists.gnu.org/archive/html/emacs-devel/2014-10/msg00567.html). Nasty little issue. – Malabarba Dec 15 '14 at 22:48
-
@Malabarba I'd argue that this is just a natural consequence of leaking abstractions (specifically, depending on a particular version of a macro), and another reason why I am **very** careful to use macros. You'll always have these kinds of issues with macros: They are **inherent** to compile-time macros, in **any** language. That's why macros aren't cool, but rather dangerous. – Dec 15 '14 at 22:54
-
1@lunaryorn I agree macros are dangerous (I'll even edit my answer to sound less praising :), but I don't think that bug was a specific instance of it. That bug had other (less aggravating) manifestations that do not involve macros at all. It also caused problems with function dependencies. – Malabarba Dec 15 '14 at 23:41