[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Macro expansion: Why doesn't the invoked macro see (let (variables))
From: |
Stefan Monnier |
Subject: |
Re: Macro expansion: Why doesn't the invoked macro see (let (variables))from the invoking one? |
Date: |
Wed, 08 Feb 2012 14:52:45 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.0.92 (gnu/linux) |
> (defmacro run-hooks-here ()
> (setq hooks-called t) <================= flag variable
> `(run-hooks ',hook (if ,mode ',hook-on ',hook-off)))
> (defmacro define-minor-mode (....)
> ....
> (let (... hooks-run)
> ....
> ,@body <================= expand invoker's forms
This comment is wrong: ",@body" just plugs in the `body' without
macro-expanding it.
> <====== There may be (run-hooks-here) here.
> ,@(unless hooks-run `((run-hooks-here))) <========= test flag
You can do that, but you then need to make sure the `body' gets
macro-expanded while the `let' is live, i.e. during the expansion of the
call to `define-minor-mode'.
You can do it with something like
(defmacro define-minor-mode (....)
....
(let (... hooks-run)
....
,@(macroexpand-all body) <================= expand invoker's forms
<====== There may be (run-hooks-here) here.
,@(unless hooks-run `((run-hooks-here))) <========= test flag
But note that this counts as ugly. We use such tricks in cl-macs.el to
figure out whether `body' uses `return-from' within a `block' (in order
to optimize away the `catch' that's otherwise needed), but it's ugly,
inefficient, and brittle.
An :after-hook (or :late-code or some other name you prefer) is much
better in this regard.
Stefan
Re: Macro expansion: Why doesn't the invoked macro see (let (variables)) from the invoking one?, Tassilo Horn, 2012/02/08