>>>"RC" == Rick Campbell schrieb am Thu, 27 Aug
1998 20:52:29 -0400:
RC> That's not really true. All forms are processed in order
RC> from left to right. Macros are expanded as they are reached. In
RC> compiled code, macros are expanded at compile time in such a way
RC> as not be expanded at runtime.
RC> I'm pretty sure that you're wrong about this. At the risk of
RC> being hypocritical (I didn't cite spec), can you point to
RC> something in the spec that dictates that in compiled code, macros
RC> *must* be expanded at compile time.
Here's what I've found in the HyperSpec (on defmacro):
"If a defmacro form appears as a top level form, the compiler must
store the macro definition at compile time, so that occurrences of the
macro later on in the file can be expanded correctly. Users must
ensure that the body of the macro can be evaluated at compile time if
it is referenced within the file being compiled."
I'm not sure however, that "storing" means "expanding". Hmm,
let's
have a try ... (some minutes later). I'm now convinced: don't do this
(refer to a non-special global i.e. top-level variable in a
toplevel-macro). Example:
;; The following snippet behave differently whether
;; compiled or interpreted (i.e. evaluated at top-level)
(setq gee 23)
(format t "gee => ~d~%" gee)
(defmacro fun ()
gee)
(format t "(fun) => ~d~%"
(fun))
(defun baz ()
(fun))
(format t "(baz) => ~d~%"
(baz))
(setq gee 42)
(format t "(setq gee 42)~%")
(format t "(fun) => ~d~%" (fun))
(format t "(baz) => ~d~%"
(baz))
(fun) should (according to Michael) refer to 23 and should not be
affected by setting gee to 42.
Use a plain lisp, and try to compile it (don't load it in advance):
Warning: Free reference to undeclared variable GEE assumed special.
; While compiling (:TOP-LEVEL-FORM "defmacro-test.lisp" 315):
Error: Attempt to take the value of the unbound variable `GEE'.
[condition type: UNBOUND-VARIABLE]
This happens when the compiler tries to compile the first
format-expression. Okay, now load the file above first (again in a
fresh started acl):
USER(8): (load "lisp/defmacro-test.lisp")
; Loading lisp/defmacro-test.lisp
gee => 23
(fun) => 23
(baz) => 23
(setq gee 42)
(fun) => 42
(baz) => 42
T
Now compiling works. After compilation:
USER(10): gee
42
USER(11): (fun)
42
USER(12): (baz)
42
Reloading the compiled file:
USER(13): (load "lisp/defmacro-test")
; Fast loading lisp/defmacro-test.fasl
gee => 23
(fun) => 42
(baz) => 42
(setq gee 42)
(fun) => 42
(baz) => 42
T
Set gee to 57:
USER(14): (setq gee 57)
57
USER(16): (fun)
57
USER(17): (baz)
42
Baz still refers to 42, since the macro has been expanded when baz was
compiled and gee had the value of 42 then. fun OTOH expands its current
current lexical environment which has gee set to 57 (note that still
USER(18): (let ((gee 63)) (fun))
57
as fun is expanded in a different lexical environment, namely the one
in which it was defined. However, the settings of this environment can
be changed.)
Michael, in Scheme, to which values would baz and fun evaluate ?
As I have tried to point out, (fun) expands to the binding of gee in
its lexical environment that happens to get changed by setting gee to
42.
Holger
--
---
http://www.coling.uni-freiburg.de/~schauer ---
"Deine capslock und '!' Tasten klemmen."
"Nee, ich habe eine Win95 Tastatur."
-- Robin Socha und H.Wulff in de.comp.os.linux.misc