@end example
@deffn {Syntax} eval-when conditions exp...
- Evaluate @var{exp...} under the given @var{conditions}. Valid conditions include
- @code{eval}, @code{load}, and @code{compile}. If you need to use
- @code{eval-when}, use it with all three conditions, as in the above example.
- Other uses of @code{eval-when} may void your warranty or poison your cat.
+ Evaluate @var{exp...} under the given @var{conditions}. Valid
+ conditions include:
+
+ @table @code
+ @item expand
+ Evaluate during macro expansion, whether compiling or not.
+
+ @item load
+ Evaluate during the evaluation phase of compiled code, e.g. when loading
+ a compiled module or running compiled code at the REPL.
+
+ @item eval
+ Evaluate during the evaluation phase of non-compiled code.
+
+ @item compile
+ Evaluate during macro expansion, but only when compiling.
+ @end table
+
+ In other words, when using the primitive evaluator, @code{eval-when}
+ expressions with @code{expand} are run during macro expansion, and those
+ with @code{eval} are run during the evaluation phase.
+
+ When using the compiler, @code{eval-when} expressions with either
+ @code{expand} or @code{compile} are run during macro expansion, and
+ those with @code{load} are run during the evaluation phase.
+
+ When in doubt, use the three conditions @code{(expand load eval)}, as in
+ the example above. Other uses of @code{eval-when} may void your
+ warranty or poison your cat.
@end deffn
+@node Macro Expansion
+@subsection Macro Expansion
+
+Usually, macros are expanded on behalf of the user as needed. Macro
+expansion is an integral part of @code{eval} and @code{compile}. Users
+can also expand macros at the REPL prompt via the @code{expand} REPL
+command; @xref{Compile Commands}.
+
+Macros can also be expanded programmatically, via @code{macroexpand},
+but the details get a bit hairy for two reasons.
+
+The first complication is that the result of macro-expansion isn't
+Scheme: it's Tree-IL, Guile's high-level intermediate language.
+@xref{Tree-IL}. As ``hygienic macros'' can produce identifiers that are
+distinct but have the same name, the output format needs to be able to
+represent distinctions between variable identities and names. Again,
+@xref{Tree-IL}, for all the details. The easiest thing is to just run
+@code{tree-il->scheme} on the result of macro-expansion:
+
+@lisp
+(macroexpand '(+ 1 2))
+@result{}
+#<tree-il (call (toplevel +) (const 1) (const 2))>
+
+(use-modules (language tree-il))
+(tree-il->scheme (macroexpand '(+ 1 2)))
+@result{}
+(+ 1 2)
+@end lisp
+
+The second complication involves @code{eval-when}. As an example, what
+would it mean to macro-expand the definition of a macro?
+
+@lisp
+(macroexpand '(define-syntax qux (identifier-syntax 'bar)))
+@result{}
+?
+@end lisp
+
+The answer is that it depends who is macro-expanding, and why. Do you
+define the macro in the current environment? Residualize a macro
+definition? Both? Neither? The default is to expand in ``eval'' mode,
+which means an @code{eval-when} clauses will only proceed when
+@code{eval} (or @code{expand}) is in its condition set. Top-level
+macros will be @code{eval}'d in the top-level environment.
+
+In this way @code{(macroexpand @var{foo})} is equivalent to
+@code{(macroexpand @var{foo} 'e '(eval))}. The second argument is the
+mode (@code{'e} for ``eval'') and the second is the
+eval-syntax-expanders-when parameter (only @code{eval} in this default
+setting).
+
+But if you are compiling the macro definition, probably you want to
+reify the macro definition itself. In that case you pass @code{'c} as
+the second argument to @code{macroexpand}. But probably you want the
+macro definition to be present at compile time as well, so you pass
+@code{'(compile load eval)} as the @var{esew} parameter. In fact
+@code{(compile @var{foo} #:to 'tree-il)} is entirely equivalent to
+@code{(macroexpand @var{foo} 'c '(compile load eval))}; @xref{The Scheme
+Compiler}.
+
+It's a terrible interface; we know. The macroexpander is somewhat
+tricksy regarding modes, so unless you are building a macro-expanding
+tool, we suggest to avoid invoking it directly.
+
+
+@node Hygiene and the Top-Level
+@subsection Hygiene and the Top-Level
+
+Consider the following macro.
+
+@lisp
+(define-syntax-rule (defconst name val)
+ (begin
+ (define t val)
+ (define-syntax-rule (name) t)))
+@end lisp
+
+If we use it to make a couple of bindings:
+
+@lisp
+(defconst foo 42)
+(defconst bar 37)
+@end lisp
+
+The expansion would look something like this:
+
+@lisp
+(begin
+ (define t 42)
+ (define-syntax-rule (foo) t))
+(begin
+ (define t 37)
+ (define-syntax-rule (bar) t))
+@end lisp
+
+As the two @code{t} bindings were introduced by the macro, they should
+be introduced hygienically -- and indeed they are, inside a lexical
+contour (a @code{let} or some other lexical scope). The @code{t}
+reference in @code{foo} is distinct to the reference in @code{bar}.
+
+At the top-level things are more complicated. Before Guile 2.2, a use
+of @code{defconst} at the top-level would not introduce a fresh binding
+for @code{t}. This was consistent with a weaselly interpretation of the
+Scheme standard, in which all possible bindings may be assumed to exist,
+at the top-level, and in which we merely take advantage of toplevel
+@code{define} of an existing binding being equivalent to @code{set!}.
+But it's not a good reason.
+
+The solution is to create fresh names for all bindings introduced by
+macros -- not just bindings in lexical contours, but also bindings
+introduced at the top-level.
+
+However, the obvious strategy of just giving random names to introduced
+toplevel identifiers poses a problem for separate compilation. Consider
+without loss of generality a @code{defconst} of @code{foo} in module
+@code{a} that introduces the fresh top-level name @code{t-1}. If we
+then compile a module @code{b} that uses @code{foo}, there is now a
+reference to @code{t-1} in module @code{b}. If module @code{a} is then
+expanded again, for whatever reason, for example in a simple
+recompilation, the introduced @code{t} gets a fresh name; say,
+@code{t-2}. Now module @code{b} has broken because module @code{a} no
+longer has a binding for @code{t-1}.
+
+If introduced top-level identifiers ``escape'' a module, in whatever
+way, they then form part of the binary interface (ABI) of a module. It
+is unacceptable from an engineering point of view to allow the ABI to
+change randomly. (It also poses practical problems in meeting the
+recompilation conditions of the Lesser GPL license, for such modules.)
+For this reason many people prefer to never use identifier-introducing
+macros at the top-level, instead making those macros receive the names
+for their introduced identifiers as part of their arguments, or to
+construct them programmatically and use @code{datum->syntax}. But this
+approach requires omniscience as to the implementation of all macros one
+might use, and also limits the expressive power of Scheme macros.
+
+There is no perfect solution to this issue. Guile does a terrible thing
+here. When it goes to introduce a top-level identifier, Guile gives the
+identifier a pseudo-fresh name: a name that depends on the hash of the
+source expression in which the name occurs. The result in this case is
+that the introduced definitions expand as:
+
+@lisp
+(begin
+ (define t-1dc5e42de7c1050c 42)
+ (define-syntax-rule (foo) t-1dc5e42de7c1050c))
+(begin
+ (define t-10cb8ce9fdddd6e9 37)
+ (define-syntax-rule (bar) t-10cb8ce9fdddd6e9))
+@end lisp
+
+However, note that as the hash depends solely on the expression
+introducing the definition, we also have:
+
+@lisp
+(defconst baz 42)
+@result{} (begin
+ (define t-1dc5e42de7c1050c 42)
+ (define-syntax-rule (baz) t-1dc5e42de7c1050c))
+@end lisp
+
+Note that the introduced binding has the same name! This is because the
+source expression, @code{(define t 42)}, was the same. Probably you
+will never see an error in this area, but it is important to understand
+the components of the interface of a module, and that interface may
+include macro-introduced identifiers.
+
+
@node Internal Macros
@subsection Internal Macros
;;; installed-scm-file
- ;;;; Copyright (C) 1998,1999,2000,2001,2002, 2003, 2006, 2009, 2010, 2011, 2013 Free Software Foundation, Inc.
-;;;; Copyright (C) 1998,1999,2000,2001,2002, 2003, 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
++;;;; Copyright (C) 1998,1999,2000,2001,2002, 2003, 2006, 2009, 2010, 2011, 2013, 2014 Free Software Foundation, Inc.
;;;; Copyright (C) 1993-1998 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
;;;;
;;;; This library is free software; you can redistribute it and/or
(define *goops-module* (current-module))
;; First initialize the builtin part of GOOPS
- (eval-when (eval load compile)
+ (eval-when (expand load eval)
(%init-goops-builtins))
- (eval-when (eval load compile)
+ (eval-when (expand load eval)
(use-modules ((language tree-il primitives) :select (add-interesting-primitive!)))
- (add-interesting-primitive! 'class-of)
- (define (@slot-ref o n)
- (struct-ref o n))
- (define (@slot-set! o n v)
- (struct-set! o n v))
- (add-interesting-primitive! '@slot-ref)
- (add-interesting-primitive! '@slot-set!))
+ (add-interesting-primitive! 'class-of))
;; Then load the rest of GOOPS
(use-modules (oop goops util)
(oop goops compile))
\f
- (eval-when (eval load compile)
+;; FIXME: deprecate.
+ (eval-when (expand load eval)
(define min-fixnum (- (expt 2 29)))
(define max-fixnum (- (expt 2 29) 1)))