[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#13813: 24.3.50; eval-and-compile in macro inhibits let-binding of va
From: |
Stefan Monnier |
Subject: |
bug#13813: 24.3.50; eval-and-compile in macro inhibits let-binding of variable |
Date: |
Mon, 25 Feb 2013 15:53:21 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux) |
> Recipe:
> * Create a file test.el with the following contents:
> (defvar myflag nil)
> (defmacro mytestmacro ()
> "An eval-and-compile test."
> `(eval-and-compile (mytestfun)))
> (defun mytestfun ()
> (when myflag
> (message "foo")))
> (let ((myflag t))
> ;; Should display "foo"
> (mytestmacro))
> * Now call with Emacs from trunk:
> emacs --batch -l test.el
> * "foo" should be displayed, but isn't. The Emacs 24.2.93 pretest
> however works as expected.
OK, you got me, I admit it, my recent change to eval-and-compile makes
it a lie. Basically, there are now 3 different times:
- compile-time
- load-time (aka "eager-macroexpansion")
- eval-time
Most eval-and-compile are used for definitions which are used in macros
(hence needed for both compile-time and load-time). For this reason,
I changed recently eval-and-compile to be (in effect)
eval-during-load-and-compile. I could turn it into
a eval-during-eval-load-and-compile, but then your above test would run
`mytestfun' twice (once with myflag=nil and then once with myflag=t)
which I don't think would please everyone either.
> * Note the following:
> - It works if you just 'setq' the 'myflag' variable
But not if you (progn (setq myflag t) (mytestmacro)). The issue is
whether the setq takes place in a separate top-level expression, in
which case it's run before eager-macroexpansion of the expression that
does the (mytestmacro).
> - The same problem occurs with `eval-when-compile', but everything
> works with `progn'.
Yes, it's basically the same problem.
> And yes, Stefan, this bug turned up in the EIEIO test suite. :-)
Could you give some details, so we can better assess the best solution?
BTW, I think eval-and-compile should only be used to wrap definitions.
Anything else is asking for trouble.
Stefan