350 lines
24 KiB
HTML
350 lines
24 KiB
HTML
<!-- Common Lisp HyperSpec (TM), version 7.0 generated by Kent M. Pitman on Mon, 11-Apr-2005 2:31am EDT -->
|
|
<HTML>
|
|
<HEAD>
|
|
<TITLE>CLHS: Issue DEFINE-COMPILER-MACRO Writeup</TITLE>
|
|
<LINK HREF="../Data/clhs.css" REL="stylesheet" TYPE="text/css" />
|
|
<META HTTP-EQUIV="Author" CONTENT="Kent M. Pitman">
|
|
<META HTTP-EQUIV="Organization" CONTENT="LispWorks Ltd.">
|
|
<LINK REL=TOP HREF="../Front/index.htm">
|
|
<LINK REL=COPYRIGHT HREF="../Front/Help.htm#Legal">
|
|
<LINK REL=DISCLAIMER HREF="../Front/Help.htm#Disclaimer">
|
|
<LINK REL=PREV HREF="../Issues/iss100_w.htm">
|
|
<LINK REL=UP HREF="../Issues/iss101.htm">
|
|
<LINK REL=NEXT HREF="../Issues/iss102_w.htm">
|
|
</HEAD>
|
|
<BODY>
|
|
<H1><A REV=MADE HREF="http://www.lispworks.com/"><IMG WIDTH=80 HEIGHT=65 ALT="[LISPWORKS]" SRC="../Graphics/LWSmall.gif" ALIGN=Bottom></A><A REL=TOP HREF="../Front/index.htm"><IMG WIDTH=237 HEIGHT=65 ALT="[Common Lisp HyperSpec (TM)]" SRC="../Graphics/CLHS_Sm.gif" ALIGN=Bottom></A> <A REL=PREV HREF="../Issues/iss100_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Previous]" SRC="../Graphics/Prev.gif" ALIGN=Bottom></A><A REL=UP HREF="../Issues/iss101.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Up]" SRC="../Graphics/Up.gif" ALIGN=Bottom></A><A REL=NEXT HREF="../Issues/iss102_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
|
|
|
|
<HR>
|
|
|
|
|
|
|
|
<H2>Issue DEFINE-COMPILER-MACRO Writeup</H2>
|
|
|
|
<PRE><B>Forum:</B> Cleanup<P>
|
|
<B>Issue:</B> <A REL=DEFINITION HREF="../Body/m_define.htm#define-compiler-macro"><B>DEFINE-COMPILER-MACRO</B></A><P>
|
|
Related Issues: Issue DEFINE-OPTIMIZER<P>
|
|
Issue <A HREF="iss342.htm">SYNTACTIC-ENVIRONMENT-ACCESS</A><P>
|
|
Issue <A HREF="iss214.htm">LISP-SYMBOL-REDEFINITION</A><P>
|
|
Issue <A HREF="iss104.htm">DEFINING-MACROS-NON-TOP-LEVEL</A><P>
|
|
Issue <A HREF="iss147.htm">EVAL-WHEN-NON-TOP-LEVEL</A><P>
|
|
<B>References:</B> CLtL p. 151, p. 152<P>
|
|
<B>Category:</B> ADDITION<P>
|
|
<B>Edit-History:</B> 28-Jun-89, Version 1 by JonL White and Steve Haflich<P>
|
|
12-Jul-89, Version 2 by Loosemore<P>
|
|
24-Oct-89, Version 3 by Loosemore<P>
|
|
19-Oct-90, Version 4 by Loosemore<P>
|
|
<B>Status:</B> Version 2 (proposal NEW-FACILITY) passed at June 89 meeting<P>
|
|
Version 4 (proposal X3J13-NOV89) passed at Nov 89 meeting<P>
|
|
(replaces proposal NEW-FACILITY)<P>
|
|
<P>
|
|
<P>
|
|
<B>Problem Description:<P>
|
|
</B><P>
|
|
Occasionally one would like to define a macro which is expanded only<P>
|
|
"in the compiler", but which would not normally affect the actions of<P>
|
|
the interpreter. For example, the OSS/Generator proposal has several<P>
|
|
functions for which it would like to specify some alternative source<P>
|
|
code sequences for the compiler to compiler, rather than just<P>
|
|
compiling a closed-call to the function.<P>
|
|
<P>
|
|
Also, it is occasionally desirable for a macro expansion to be<P>
|
|
different based on the various compiler optimization qualities (e.g.,<P>
|
|
<A REL=DEFINITION HREF="../Body/d_optimi.htm#speed"><B>SPEED</B></A>, <A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>SAFETY</B></A>, and so on); but if the expansion is for the interpreter<P>
|
|
rather than the compiler, then such variation based on compiler<P>
|
|
optimizers is not needed.<P>
|
|
<P>
|
|
So-called "compiler optimizers" are just a special case of macro-like<P>
|
|
expansions, which are limited to being done "in the compiler" and<P>
|
|
which are generally required to produce semantically equivalent code<P>
|
|
to replace an apparent function call. There is a need for a facility<P>
|
|
that at least covers this capability.<P>
|
|
<P>
|
|
<P>
|
|
<P>
|
|
<P>
|
|
<B>Proposal: (DEFINE-COMPILER-MACRO:X3J13-NOV89):<P>
|
|
</B><P>
|
|
Add the concept of "compiler macros" to the language, along with the<P>
|
|
defining macro <A REL=DEFINITION HREF="../Body/m_define.htm#define-compiler-macro"><B>DEFINE-COMPILER-MACRO</B></A> and accessor function<P>
|
|
<A REL=DEFINITION HREF="../Body/f_cmp_ma.htm#compiler-macro-function"><B>COMPILER-MACRO-FUNCTION</B></A>.<P>
|
|
<P>
|
|
<P>
|
|
(1) What compiler macros are<P>
|
|
<P>
|
|
The purpose of this facility is to permit selective source-code<P>
|
|
transformations as optimization advice to the compiler. When a<P>
|
|
nonatomic form is being processed (as by the compiler), if the<P>
|
|
operator names a compiler macro then that compiler macro may be<P>
|
|
invoked on the form, and the resulting expansion recursively processed<P>
|
|
in preference to performing the usual processing on the original form<P>
|
|
according to its normal interpretation as a function or macro call.<P>
|
|
<P>
|
|
A compiler macro function, like an ordinary macro function, is a<P>
|
|
function of two arguments: the entire call form and the environment.<P>
|
|
Unlike an ordinary macro, a compiler macro can decline to <A REL=DEFINITION HREF="../Body/f_provid.htm#provide"><B>provide</B></A> an<P>
|
|
expansion merely by returning a value that is <A REL=DEFINITION HREF="../Body/a_eql.htm#eql"><B>EQL</B></A> to the original<P>
|
|
form. The consequences are undefined if a compiler macro function<P>
|
|
destructively modifies any part of its form argument.<P>
|
|
<P>
|
|
The form passed to the compiler macro function can either be a list<P>
|
|
whose <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>CAR</B></A> is the function name, or a list whose <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>CAR</B></A> is <A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>FUNCALL</B></A> and<P>
|
|
whose <A REL=DEFINITION HREF="../Body/f_car_c.htm#cadr"><B>CADR</B></A> is a list (<A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> <name>); note that this affects<P>
|
|
destructuring of the form argument by the compiler macro function.<P>
|
|
<A REL=DEFINITION HREF="../Body/m_define.htm#define-compiler-macro"><B>DEFINE-COMPILER-MACRO</B></A> arranges for destructuring of arguments to be<P>
|
|
performed correctly for both possible formats.<P>
|
|
<P>
|
|
<P>
|
|
(2) Naming of compiler macros<P>
|
|
<P>
|
|
Compiler macros may be defined for function names that name macros as<P>
|
|
well as functions. It is not permitted to define a compiler macro for<P>
|
|
names which are external symbols in the COMMON-LISP package; see issue<P>
|
|
<A HREF="iss214.htm">LISP-SYMBOL-REDEFINITION</A>.<P>
|
|
<P>
|
|
Compiler macro definitions are strictly global. There is no provision<P>
|
|
for defining local compiler macros in the way that <A REL=DEFINITION HREF="../Body/s_flet_.htm#macrolet"><B>MACROLET</B></A> defines<P>
|
|
local macros. Lexical bindings of a function name shadow any compiler<P>
|
|
macro definition associated with the name as well as its global<P>
|
|
function or macro definition.<P>
|
|
<P>
|
|
Note that the presence of a compiler macro definition does not affect<P>
|
|
the values returned by FUNCTION-INFORMATION, or other accessors such<P>
|
|
as <A REL=DEFINITION HREF="../Body/f_fbound.htm#fboundp"><B>FBOUNDP</B></A> or <A REL=DEFINITION HREF="../Body/f_mexp_.htm#macroexpand"><B>MACROEXPAND</B></A>. Compiler macros are global and the function<P>
|
|
<A REL=DEFINITION HREF="../Body/f_cmp_ma.htm#compiler-macro-function"><B>COMPILER-MACRO-FUNCTION</B></A> is sufficient to resolve their interaction<P>
|
|
with other lexical and global definitions.<P>
|
|
<P>
|
|
<P>
|
|
(3) When compiler macros might/must/must not be used<P>
|
|
<P>
|
|
The presence of a compiler macro definition for a function or macro<P>
|
|
indicates that it is desirable for the compiler to use the expansion<P>
|
|
of the compiler macro instead of the original function call or macro<P>
|
|
call form. However, it is not required for any language processor<P>
|
|
(compiler, evaluator, or other code walker) to actually invoke compiler<P>
|
|
macro functions, or to make use of the resulting expansion.<P>
|
|
<P>
|
|
There two situations in which a compiler macro definition must not be<P>
|
|
applied by any language processor:<P>
|
|
<P>
|
|
- The global function name binding associated with the compiler<P>
|
|
macro is shadowed by lexical rebinding of the function name.<P>
|
|
<P>
|
|
- The function name has been declared or proclaimed <A REL=DEFINITION HREF="../Body/d_inline.htm#notinline"><B>NOTINLINE</B></A> and<P>
|
|
the call form appears within the scope of the declaration.<P>
|
|
<P>
|
|
When a compiler macro function is called as part of processing by the<P>
|
|
evaluator or compiler, it is invoked by calling the function that is<P>
|
|
the value of <A REL=DEFINITION HREF="../Body/v_mexp_h.htm#STmacroexpand-hookST"><B>*MACROEXPAND-HOOK*</B></A>.<P>
|
|
<P>
|
|
When <A REL=DEFINITION HREF="../Body/f_cmp_fi.htm#compile-file"><B>COMPILE-FILE</B></A> chooses to expand a top-level compiler macro call,<P>
|
|
the expansion is also treated as a top-level form for the purposes of<P>
|
|
<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> processing, in the same way as the expansion of an ordinary<P>
|
|
macro.<P>
|
|
<P>
|
|
<P>
|
|
<P>
|
|
(4) Specification of <A REL=DEFINITION HREF="../Body/m_define.htm#define-compiler-macro"><B>DEFINE-COMPILER-MACRO</B></A><P>
|
|
<P>
|
|
<A REL=DEFINITION HREF="../Body/m_define.htm#define-compiler-macro"><B>DEFINE-COMPILER-MACRO</B></A> name lambda-list<P>
|
|
[[ {declaration}* | doc-string ]] {form}* [macro]<P>
|
|
<P>
|
|
<A REL=DEFINITION HREF="../Body/m_define.htm#define-compiler-macro"><B>DEFINE-COMPILER-MACRO</B></A> is the normal mechanism for defining a compiler<P>
|
|
macro function. Its syntax resembles that of <A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A>. The function<P>
|
|
is defined in the lexical environment in which the <A REL=DEFINITION HREF="../Body/m_define.htm#define-compiler-macro"><B>DEFINE-COMPILER-MACRO</B></A><P>
|
|
form appears; see issue <A HREF="iss104.htm">DEFINING-MACROS-NON-TOP-LEVEL</A>.<P>
|
|
<P>
|
|
The <name> must be a function name.<P>
|
|
<P>
|
|
The <lambda-list> supports destructuring and may include <A REL=DEFINITION HREF="../Body/03_dd.htm#AMenvironment"><B>&ENVIRONMENT</B></A><P>
|
|
and <A REL=DEFINITION HREF="../Body/03_dd.htm#AMwhole"><B>&WHOLE</B></A>, in the same way as a <A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> lambda-list. The <A REL=DEFINITION HREF="../Body/03_dd.htm#AMwhole"><B>&WHOLE</B></A><P>
|
|
argument is bound to the form argument that is passed to the compiler<P>
|
|
macro function. The remaining lambda-list parameters are specified<P>
|
|
as if this form contained the function name in the <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>CAR</B></A> and the actual<P>
|
|
arguments in the <A REL=DEFINITION HREF="../Body/f_car_c.htm#cdr"><B>CDR</B></A>, but if the <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>CAR</B></A> of the actual form is the symbol<P>
|
|
<A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>FUNCALL</B></A>, then the destructuring of the the arguments will actually be<P>
|
|
performed using its <A REL=DEFINITION HREF="../Body/f_car_c.htm#cddr"><B>CDDR</B></A> instead.<P>
|
|
<P>
|
|
When a call to <A REL=DEFINITION HREF="../Body/m_define.htm#define-compiler-macro"><B>DEFINE-COMPILER-MACRO</B></A> appears at top-level in a file<P>
|
|
being compiled by <A REL=DEFINITION HREF="../Body/f_cmp_fi.htm#compile-file"><B>COMPILE-FILE</B></A>, the compiler macro definition is made<P>
|
|
known to the file compiler (analagous to the way top-level <A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A><P>
|
|
calls are handled).<P>
|
|
<P>
|
|
<P>
|
|
<P>
|
|
<P>
|
|
(5) Specification of <A REL=DEFINITION HREF="../Body/f_cmp_ma.htm#compiler-macro-function"><B>COMPILER-MACRO-FUNCTION</B></A><P>
|
|
<P>
|
|
<A REL=DEFINITION HREF="../Body/f_cmp_ma.htm#compiler-macro-function"><B>COMPILER-MACRO-FUNCTION</B></A> name &optional env [function]<P>
|
|
<P>
|
|
This is the accessor for the compiler macro definition associated<P>
|
|
with a given name.<P>
|
|
<P>
|
|
The <name> argument must be a function name. If there is a compiler<P>
|
|
macro definition associated with that name in the given environment<P>
|
|
<env>, <A REL=DEFINITION HREF="../Body/f_cmp_ma.htm#compiler-macro-function"><B>COMPILER-MACRO-FUNCTION</B></A> returns that function; otherwise it<P>
|
|
returns <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>.<P>
|
|
<P>
|
|
If there is a local function or macro named <name> defined in the<P>
|
|
environment <env>, this definition shadows any global compiler macro<P>
|
|
definition for that <name> and <A REL=DEFINITION HREF="../Body/f_cmp_ma.htm#compiler-macro-function"><B>COMPILER-MACRO-FUNCTION</B></A> must return<P>
|
|
<A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>.<P>
|
|
<P>
|
|
<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> may be used with <A REL=DEFINITION HREF="../Body/f_cmp_ma.htm#compiler-macro-function"><B>COMPILER-MACRO-FUNCTION</B></A> to install a compiler<P>
|
|
macro function for the name <name>, analogously to using <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> on<P>
|
|
<A REL=DEFINITION HREF="../Body/f_macro_.htm#macro-function"><B>MACRO-FUNCTION</B></A>. The value must be a function of two arguments, as<P>
|
|
described above. It is also permissible to <A REL=DEFINITION HREF="../Body/f_provid.htm#provide"><B>provide</B></A> a value of <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> to<P>
|
|
remove any existing compiler macro definition. The <env> argument to<P>
|
|
<A REL=DEFINITION HREF="../Body/f_cmp_ma.htm#compiler-macro-function"><B>COMPILER-MACRO-FUNCTION</B></A> must be omitted when it appears as a <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A><P>
|
|
place.<P>
|
|
<P>
|
|
<P>
|
|
<P>
|
|
<P>
|
|
<B>Proposal: (DEFINE-COMPILER-MACRO:NEW-FACILITY):<P>
|
|
</B><P>
|
|
Introduce a new facility by additions as follows:<P>
|
|
<P>
|
|
Macro:<P>
|
|
<P>
|
|
<A REL=DEFINITION HREF="../Body/m_define.htm#define-compiler-macro"><B>DEFINE-COMPILER-MACRO</B></A> name lambda-list {doc-string} {declarations}* {form}*<P>
|
|
<P>
|
|
This is just like <A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> except the definition isn't stored in the<P>
|
|
symbol function cell of 'name', and isn't seen by <A REL=DEFINITION HREF="../Body/f_mexp_.htm#macroexpand-1"><B>MACROEXPAND-1</B></A> (but<P>
|
|
is seen by COMPILER-MACROEXPAND-1 -- see below). Like <A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A>, the<P>
|
|
lambdalist may include <A REL=DEFINITION HREF="../Body/03_dd.htm#AMenvironment"><B>&ENVIRONMENT</B></A> and <A REL=DEFINITION HREF="../Body/03_dd.htm#AMwhole"><B>&WHOLE</B></A>. The definition is<P>
|
|
"global"; there is no explicit provision for defining local compiler<P>
|
|
macros in the way that <A REL=DEFINITION HREF="../Body/s_flet_.htm#macrolet"><B>MACROLET</B></A> defines local macros.<P>
|
|
<P>
|
|
A toplevel call to <A REL=DEFINITION HREF="../Body/m_define.htm#define-compiler-macro"><B>DEFINE-COMPILER-MACRO</B></A> in a file being compiled by<P>
|
|
<A REL=DEFINITION HREF="../Body/f_cmp_fi.htm#compile-file"><B>COMPILE-FILE</B></A> has an effect on the compilation environment similar to<P>
|
|
what a call to <A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> would have, except it is noticed as a<P>
|
|
"compiler macro".<P>
|
|
<P>
|
|
<P>
|
|
Function:<P>
|
|
<P>
|
|
<A REL=DEFINITION HREF="../Body/f_cmp_ma.htm#compiler-macro-function"><B>COMPILER-MACRO-FUNCTION</B></A> name <A REL=DEFINITION HREF="../Body/03_da.htm#AMoptional"><B>&OPTIONAL</B></A> env<P>
|
|
<P>
|
|
If 'name' is a symbol that has been defined as a compiler macro, then<P>
|
|
calling <A REL=DEFINITION HREF="../Body/f_cmp_ma.htm#compiler-macro-function"><B>COMPILER-MACRO-FUNCTION</B></A> on it returns the macro expansion<P>
|
|
function; otherwise it returns <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>. 'name' must be a symbol. The<P>
|
|
local lexical environment may override a global definition for 'name'<P>
|
|
by defining a local function or local macro (such as by <A REL=DEFINITION HREF="../Body/s_flet_.htm#flet"><B>FLET</B></A>,<P>
|
|
<A REL=DEFINITION HREF="../Body/s_flet_.htm#macrolet"><B>MACROLET</B></A>, etc.), in which case <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> is returned; the optional argument<P>
|
|
'env' is provided so that clients may pass in &environment objects for<P>
|
|
this purpose.<P>
|
|
<P>
|
|
<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> may be used with <A REL=DEFINITION HREF="../Body/f_cmp_ma.htm#compiler-macro-function"><B>COMPILER-MACRO-FUNCTION</B></A> to install a function as<P>
|
|
the expansion function for the compiler macro 'name', analogously to<P>
|
|
using <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> on <A REL=DEFINITION HREF="../Body/f_macro_.htm#macro-function"><B>MACRO-FUNCTION</B></A>. <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A>'ing to <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> removes any existing<P>
|
|
compiler macro definition. Like <A REL=DEFINITION HREF="../Body/f_macro_.htm#macro-function"><B>MACRO-FUNCTION</B></A>, the <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> value (if not<P>
|
|
<A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>) must be a function of two arguments: the entire macro call, and<P>
|
|
the environment. The second argument to <A REL=DEFINITION HREF="../Body/f_cmp_ma.htm#compiler-macro-function"><B>COMPILER-MACRO-FUNCTION</B></A> must<P>
|
|
be omitted when it is SETFed.<P>
|
|
<P>
|
|
<P>
|
|
Functions:<P>
|
|
<P>
|
|
COMPILER-MACROEXPAND form <A REL=DEFINITION HREF="../Body/03_da.htm#AMoptional"><B>&OPTIONAL</B></A> env<P>
|
|
COMPILER-MACROEXPAND-1 form <A REL=DEFINITION HREF="../Body/03_da.htm#AMoptional"><B>&OPTIONAL</B></A> env<P>
|
|
<P>
|
|
This is just like <A REL=DEFINITION HREF="../Body/f_mexp_.htm#macroexpand"><B>MACROEXPAND</B></A> and <A REL=DEFINITION HREF="../Body/f_mexp_.htm#macroexpand-1"><B>MACROEXPAND-1</B></A> (see CLtL p.151)<P>
|
|
except that the expander function is obtained as if by a call to<P>
|
|
<A REL=DEFINITION HREF="../Body/f_cmp_ma.htm#compiler-macro-function"><B>COMPILER-MACRO-FUNCTION</B></A> on the <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>CAR</B></A> of 'form' rather than by a call to<P>
|
|
<A REL=DEFINITION HREF="../Body/f_macro_.htm#macro-function"><B>MACRO-FUNCTION</B></A>. There are three cases wherein no expansion happens:<P>
|
|
<P>
|
|
(1) There is no compiler macro definition for the <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>CAR</B></A> of 'form';<P>
|
|
(2) There is such a definition but there is also a <A REL=DEFINITION HREF="../Body/d_inline.htm#notinline"><B>NOTINLINE</B></A><P>
|
|
declaration, either globally or in the lexical environment 'env';<P>
|
|
(3) A global compiler macro definition is shadowed by a local<P>
|
|
function or macro definition (such as by <A REL=DEFINITION HREF="../Body/s_flet_.htm#flet"><B>FLET</B></A>, <A REL=DEFINITION HREF="../Body/s_flet_.htm#labels"><B>LABELS</B></A>, or <A REL=DEFINITION HREF="../Body/s_flet_.htm#macrolet"><B>MACROLET</B></A>).<P>
|
|
<P>
|
|
Note that if there is no expansion, the original form is returned as<P>
|
|
the first value, and <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> as the second value.<P>
|
|
<P>
|
|
When COMPILER-MACROEXPAND-1 discovers that there is to be an expansion<P>
|
|
it does it by calling the function in <A REL=DEFINITION HREF="../Body/v_mexp_h.htm#STmacroexpand-hookST"><B>*MACROEXPAND-HOOK*</B></A> (see CltL p.152).<P>
|
|
<P>
|
|
<P>
|
|
The purpose of this facility is to permit selective source-code<P>
|
|
transformations based on whether the compiler is processing the code.<P>
|
|
When the compiler is about to compile a nonatomic form, it first calls<P>
|
|
COMPILER-MACROEXPAND-1 repeatedly until there is no more expansion<P>
|
|
(there might not be any to begin with). Then it continues its<P>
|
|
remaining processing, which may include calling <A REL=DEFINITION HREF="../Body/f_mexp_.htm#macroexpand-1"><B>MACROEXPAND-1</B></A> etc.<P>
|
|
<P>
|
|
The compiler is required to expand compiler macros; it is unspecified<P>
|
|
whether the interpreter does so. The intention is that only the<P>
|
|
compiler will do so, but the range of possible "compiled-only"<P>
|
|
implementation strategies precludes any firm specification.<P>
|
|
<P>
|
|
Note that a compiler macro may decline to <A REL=DEFINITION HREF="../Body/f_provid.htm#provide"><B>provide</B></A> any expansion merely<P>
|
|
by returning the original form; this is useful when using the facility<P>
|
|
to put "compiler optimizers" on various function names. For example,<P>
|
|
here is a compiler macro that "optimizes" the 0- and 1-argument cases of<P>
|
|
a function called PLUS:<P>
|
|
<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_define.htm#define-compiler-macro"><B>define-compiler-macro</B></A> plus (<A REL=DEFINITION HREF="../Body/03_dd.htm#AMwhole"><B>&whole</B></A> form <A REL=DEFINITION HREF="../Body/03_da.htm#AMrest"><B>&rest</B></A> args)<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_case_.htm#case"><B>case</B></A> (<A REL=DEFINITION HREF="../Body/f_length.htm#length"><B>length</B></A> args)<P>
|
|
(0 0)<P>
|
|
(1 (<A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> args))<P>
|
|
(t form)))<P>
|
|
<P>
|
|
The issue <A HREF="iss214.htm">LISP-SYMBOL-REDEFINITION</A> precludes user definition of any<P>
|
|
compiler macros for symbols external in the Lisp package that have a<P>
|
|
definition as a function, macro, or special form.<P>
|
|
<P>
|
|
Note that compiler macros do not appear in information returned by<P>
|
|
FUNCTION-INFORMATION; they are global, and their interaction<P>
|
|
with other lexical and global definitions can be reconstructed by<P>
|
|
<A REL=DEFINITION HREF="../Body/f_cmp_ma.htm#compiler-macro-function"><B>COMPILER-MACRO-FUNCTION</B></A>. It is up to code-walking programs to decide<P>
|
|
whether to invoke compiler macro expansion.<P>
|
|
<P>
|
|
<P>
|
|
Rationale:<P>
|
|
<P>
|
|
Many implementations have it. Many users have requested a way to add<P>
|
|
source-code "optimizers" to the compiler.<P>
|
|
<P>
|
|
Other than <A REL=DEFINITION HREF="../Body/d_inline.htm#inline"><B>INLINE</B></A> declarations for functions there is no other way to<P>
|
|
customize how calls to a specific function are compiled. <A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> is<P>
|
|
not usable for this purpose since it requires use of the<P>
|
|
<A REL=DEFINITION HREF="../Body/f_symb_1.htm#symbol-function"><B>symbol-function</B></A> cell, which would prevent the functional definition<P>
|
|
from being active in the compilation environment.<P>
|
|
<P>
|
|
<P>
|
|
<P>
|
|
<B>Current Practice:<P>
|
|
</B><P>
|
|
Lucid, Franz, and Symbolics have very similar facilities. Hunoz about<P>
|
|
the others?<P>
|
|
<P>
|
|
<P>
|
|
<B>Cost to Implementors:<P>
|
|
</B><P>
|
|
Minor: implement a <A REL=DEFINITION HREF="../Body/t_method.htm#method"><B>method</B></A> for storing named expansion functions, and<P>
|
|
tweak the compiler in one or two places.<P>
|
|
<P>
|
|
<P>
|
|
<B>Cost to Users:<P>
|
|
</B><P>
|
|
None. This is an upward-compatible addition.<P>
|
|
<P>
|
|
<P>
|
|
<B>Benefits:<P>
|
|
</B><P>
|
|
Increased portability for clients of the existing facilities.<P>
|
|
<P>
|
|
<P>
|
|
<B>Discussion:<P>
|
|
</B><P>
|
|
There has been extensive discussion under the issue DEFINE-OPTIMIZER.<P>
|
|
</PRE>
|
|
<HR>
|
|
|
|
<A REL=NAVIGATOR HREF="../Front/StartPts.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Starting Points]" SRC="../Graphics/StartPts.gif" ALIGN=Bottom></A><A REL=TOC HREF="../Front/Contents.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Contents]" SRC="../Graphics/Contents.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Master.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Index]" SRC="../Graphics/Index.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Symbol.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Symbols]" SRC="../Graphics/Symbols.gif" ALIGN=Bottom></A><A REL=GLOSSARY HREF="../Body/26_a.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Glossary]" SRC="../Graphics/Glossary.gif" ALIGN=Bottom></A><A HREF="../Front/X3J13Iss.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Issues]" SRC="../Graphics/Issues.gif" ALIGN=Bottom></A><BR>
|
|
|
|
<A REL=COPYRIGHT HREF="../Front/Help.htm#Legal"><I>Copyright 1996-2005, LispWorks Ltd. All rights reserved.</I></A><P>
|
|
</BODY>
|
|
</HTML>
|