X3J13 voted in June 1989 to add a facility for deﬁning compiler macros that take eﬀect only when compiling code, not when interpreting it.
The purpose of this facility is to permit selective source-code transformations only when the compiler is processing the code. When the compiler is about to compile a non-atomic form, it ﬁrst calls compiler-macroexpand-1 repeatedly until there is no more expansion (there might not be any to begin with). Then it continues its remaining processing, which may include calling macroexpand-1 and so on.
The compiler is required to expand compiler macros. It is unspeciﬁed whether the interpreter does so. The intention is that only the compiler will do so, but the range of possible “compiled-only” implementation strategies precludes any ﬁrm speciﬁcation.
This is just like defmacro except the deﬁnition is not stored in the symbol function cell of name and is not seen by macroexpand-1. It is, however, seen by compiler-macroexpand-1. As with defmacro, the lambda-list may include &environment and &whole and may include destructuring. The deﬁnition is global. (There is no provision for deﬁning local compiler macros in the way that macrolet deﬁnes local macros.)
A top-level call to deﬁne-compiler-macro in a ﬁle being compiled by compile-ﬁle has an eﬀect on the compilation environment similar to that of a call to defmacro, except it is noticed as a compiler macro (see section 24.1).
Note that compiler macro deﬁnitions do not appear in information returned by function-information; they are global, and their interaction with other lexical and global deﬁnitions can be reconstructed by compiler-macro-function. It is up to code-walking programs to decide whether to invoke compiler macro expansion.
X3J13 voted in March 1988 to specify that the body of the expander function deﬁned by defmacro is implicitly enclosed in a block construct whose name is the same as the name of the deﬁned macro; presumably this applies also to deﬁne-compiler-macro. Therefore return-from may be used to exit from the function.
[Function]compiler-macro-function name &optional env
The name must be a symbol. If it has been deﬁned as a compiler macro, then compiler-macro-function returns the macro expansion function; otherwise it returns nil. The lexical environment env may override any global deﬁnition for name by deﬁning a local function or local macro (such as by ﬂet, labels, or macrolet) in which case nil is returned.
setf may be used with compiler-macro-function to install a function as the expansion function for the compiler macro name, in the same manner as for macro-function. Storing the value nil removes any existing compiler macro deﬁnition. As with macro-function, a non-nil stored value must be a function of two arguments, the entire macro call and the environment. The second argument to compiler-macro-function must be omitted when it is used with setf.
[Function]compiler-macroexpand form &optional env
These are just like macroexpand and macroexpand-1 except that the expander function is obtained as if by a call to compiler-macro-function on the car of the form rather than by a call to macro-function. Note that compiler-macroexpand performs repeated expansion but compiler-macroexpand-1 performs at most one expansion. Two values are returned, the expansion (or the original form) and a value that is true if any expansion occurred and nil otherwise.
There are three cases where no expansion happens:
Note that if there is no expansion, the original form is returned as the ﬁrst value, and nil as the second value.
A compiler macro may decline to provide any expansion merely by returning the original form. This is useful when using the facility to put “compiler optimizers” on various function names. For example, here is a compiler macro that “optimizes” (one would hope) the zero-argument and one-argument cases of a function called plus: