Common Lisp the Language, 2nd Edition
Next: Destructuring
Up: Macros
Previous: Macro
Definition
The macroexpand
function is the conventional means for
expanding a macro call. A hook is provided for a user function to gain
control during the expansion process.
[Function]
macroexpand
form
&optional
env
macroexpand-1
form
&optional
env
If form is a macro call, then macroexpand-1
will expand the macro call once and return two values: the
expansion and t
. If form is not a macro call, then
the two values form and nil
are returned.
A form is considered to be a macro call only if it is a cons
whose car is a symbol that names a macro. The environment
env is similar to that used within the evaluator (see
evalhook
); it defaults to a null environment. Any local
macro definitions established within env by
macrolet
will be considered. If only form is given
as an argument, then the environment is effectively null, and only
global macro definitions (as established by defmacro
) will
be considered.
Macro expansion is carried out as follows. Once
macroexpand-1
has determined that a symbol names a macro,
it obtains the expansion function for that macro. The value of the
variable *macroexpand-hook*
is then called as a function of
three arguments: the expansion function, the form, and the
environment env. The value returned from this call is taken to
be the expansion of the macro call. The initial value of
*macroexpand-hook*
is funcall
, and the net
effect is to invoke the expansion function, giving it form and
env as its two arguments.
X3J13 voted in June 1988 (FUNCTION-TYPE) to specify that the value of
*macroexpand-hook*
is first coerced to a function before
being called as the expansion interface hook. Therefore its value may be
a symbol, a lambda-expression, or any object of type
function
.
X3J13 voted in March 1989 (MACRO-ENVIRONMENT-EXTENT) to specify
that macro environment objects received by a
*macroexpand-hook*
function have only dynamic extent. The
consequences are undefined if such objects are referred to outside the
dynamic extent of that particular invocation of the hook function. This
allows implementations to use somewhat more efficient techniques for
representing environment objects.
(The purpose of *macroexpand-hook*
is to facilitate various
techniques for improving interpretation speed by caching macro
expansions.)
X3J13 voted in June 1989 (MACRO-CACHING) to clarify that, while
*macroexpand-hook*
may be useful for debugging purposes,
despite the original design intent there is currently no correct
portable way to use it for caching macro expansions.
eq
) macro-call form may
appear in distinct lexical contexts. In addition, the macro-call form
may be a read-only constant (see quote
and also section 25.1).X3J13 also noted that, although there seems to be no correct portable
way to use *macroexpand-hook*
to cache macro expansions,
there is no requirement that an implementation call the macro expansion
function more than once for a given form and lexical environment.
X3J13 voted in March 1989 (SYMBOL-MACROLET-SEMANTICS) to specify
that macroexpand-1
will also expand symbol macros defined
by symbol-macrolet
; therefore a form may also be a
macro call if it is a symbol. The vote did not address the interaction
of this feature with the *macroexpand-hook*
function. An
obvious implementation choice is that the hook function is indeed called
and given a special expansion function that, when applied to the
form (a symbol) and env, will produce the expansion,
just as for an ordinary macro; but this is only my suggestion.
The evaluator expands macro calls as if through the use of
macroexpand-1
; the point is that eval
also
uses *macroexpand-hook*
.
macroexpand
is similar to macroexpand-1
,
but repeatedly expands form until it is no longer a macro call.
(In effect, macroexpand
simply calls
macroexpand-1
repeatedly until the second value returned is
nil
.) A second value of t
or nil
is returned as for macroexpand-1
, indicating whether the
original form was a macro call.
[Variable]
*macroexpand-hook*
The value of *macroexpand-hook*
is used as the expansion
interface hook by macroexpand-1
.
Next: Destructuring
Up: Macros
Previous: Macro
Definition
AI.Repository@cs.cmu.edu