1
0
Fork 0
cl-sites/HyperSpec-7-0/HyperSpec/Issues/iss101_w.htm
2024-04-01 10:24:07 +02:00

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>
&quot;in the compiler&quot;, 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 &quot;compiler optimizers&quot; are just a special case of macro-like<P>
expansions, which are limited to being done &quot;in the compiler&quot; 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 &quot;compiler macros&quot; 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> &lt;name&gt;); 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 &lt;name&gt; must be a function name.<P>
<P>
The &lt;lambda-list&gt; supports destructuring and may include <A REL=DEFINITION HREF="../Body/03_dd.htm#AMenvironment"><B>&amp;ENVIRONMENT</B></A><P>
and <A REL=DEFINITION HREF="../Body/03_dd.htm#AMwhole"><B>&amp;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>&amp;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 &amp;optional env [function]<P>
<P>
This is the accessor for the compiler macro definition associated<P>
with a given name.<P>
<P>
The &lt;name&gt; argument must be a function name. If there is a compiler<P>
macro definition associated with that name in the given environment<P>
&lt;env&gt;, <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 &lt;name&gt; defined in the<P>
environment &lt;env&gt;, this definition shadows any global compiler macro<P>
definition for that &lt;name&gt; 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 &lt;name&gt;, 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 &lt;env&gt; 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>&amp;ENVIRONMENT</B></A> and <A REL=DEFINITION HREF="../Body/03_dd.htm#AMwhole"><B>&amp;WHOLE</B></A>. The definition is<P>
&quot;global&quot;; 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>
&quot;compiler macro&quot;.<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>&amp;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 &amp;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>&amp;OPTIONAL</B></A> env<P>
COMPILER-MACROEXPAND-1 form <A REL=DEFINITION HREF="../Body/03_da.htm#AMoptional"><B>&amp;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 &quot;compiled-only&quot;<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 &quot;compiler optimizers&quot; on various function names. For example,<P>
here is a compiler macro that &quot;optimizes&quot; 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>&amp;whole</B></A> form <A REL=DEFINITION HREF="../Body/03_da.htm#AMrest"><B>&amp;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 &quot;optimizers&quot; 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>