A macro lambda list is used in describing macros defined by the operators in the next figure.
|
Figure 3.17: Operators that use Macro Lambda Lists
With the additional restriction that an environment parameter may appear only once (at any of the positions indicated), a macro lambda list has the following syntax:
.
var)
.
var)
A macro lambda list can contain the lambda list keywords shown in the next figure.
|
Figure 3.18: Lambda List Keywords used by Macro Lambda Lists
Optional parameters (introduced by &optional
) and
keyword parameters (introduced by &key
)
can be supplied in a macro lambda list,
just as in an ordinary lambda list.
Both may contain default initialization forms and supplied-p parameters.
&body
is identical in function to &rest
,
but it can be used to inform certain output-formatting
and editing functions that the remainder of the form is
treated as a body, and should be indented accordingly.
Only one of &body
or &rest
can be used at any particular level;
see Section 3.4.4.1 (Destructuring by Lambda Lists).
&body
can appear at any level of a
macro lambda list;
for details, see Section 3.4.4.1 (Destructuring by Lambda Lists).
&whole
is followed by a single variable that is bound to the
entire macro-call form; this is the value that the macro function
receives as its first argument.
If &whole
and a following variable appear,
they must appear first in lambda-list,
before any other parameter or lambda list keyword.
&whole
can appear at any level of a macro lambda list.
At inner levels, the &whole
variable is bound to
the corresponding part of the argument,
as with &rest
, but unlike &rest
, other arguments are also allowed.
The use of &whole
does not affect the pattern of arguments
specified.
&environment
is followed by a single variable that is bound
to an environment representing the lexical environment in which the
macro call is to be interpreted.
This environment
should be used with
macro-function
,
get-setf-expansion
,
compiler-macro-function
,
and
macroexpand
(for example) in computing the expansion of the macro, to ensure that any
lexical bindings or definitions established in the
compilation environment are taken into account.
&environment
can only appear at the top level of a
macro lambda list, and can only
appear once, but can appear anywhere in that list;
the &environment
parameter is bound along with &whole
before any other variables in the lambda list, regardless of where
&environment
appears in the lambda list.
The object that is bound to the
environment parameter has dynamic extent.
Destructuring allows a macro lambda list to express the structure of a macro call syntax. If no lambda list keywords appear, then the macro lambda list is a tree containing parameter names at the leaves. The pattern and the macro form must have compatible tree structure; that is, their tree structure must be equivalent, or it must differ only in that some leaves of the pattern match non-atomic objects of the macro form. For information about error detection in this situation, see Section 3.5.1.7 (Destructuring Mismatch).
A destructuring lambda list
(whether at top level or embedded)
can
be dotted, ending
in a parameter name. This situation is treated exactly as if the
parameter name that ends the list had appeared preceded by &rest
.
It is permissible for a macro form (or a subexpression of a
macro form)
to be a dotted list
only when (... &rest var)
or (... . var)
is used to match
it. It is the responsibility of the macro to recognize and deal
with such situations.
Anywhere in a macro lambda list where a parameter name can appear, and where ordinary lambda list syntax (as described in Section 3.4.1 (Ordinary Lambda Lists)) does not otherwise allow a list, a destructuring lambda list can appear in place of the parameter name. When this is done, then the argument that would match the parameter is treated as a (possibly dotted) list, to be used as an argument list for satisfying the parameters in the embedded lambda list. This is known as destructuring.
Destructuring is the process of decomposing a compound object into its component parts, using an abbreviated, declarative syntax, rather than writing it out by hand using the primitive component-accessing functions. Each component part is bound to a variable.
A destructuring operation requires an object to be decomposed, a pattern that specifies what components are to be extracted, and the names of the variables whose values are to be the components.
In data-directed destructuring, the pattern is a sample object of the type to be decomposed. Wherever a component is to be extracted, a symbol appears in the pattern; this symbol is the name of the variable whose value will be that component.
An example pattern is
(a b c)
which destructures a list of three elements. The variable a
is assigned
to the first element, b
to the second, etc. A more complex example
is
((first . rest) . more)
The important features of data-directed destructuring are its syntactic simplicity and the ability to extend it to lambda-list-directed destructuring.
An extension of data-directed destructuring of trees is lambda-list-directed destructuring. This derives from the analogy between the three-element destructuring pattern
(first second third)
and the three-argument lambda list
(first second third)
Lambda-list-directed destructuring is identical to data-directed destructuring
if no lambda list keywords appear in the pattern.
Any list in the pattern (whether a sub-list or the whole pattern itself)
that contains a lambda list keyword is interpreted specially.
Elements of the list to the left of the first
lambda list keyword are treated as destructuring patterns, as usual, but the
remaining elements of the list are treated like a function's
lambda list
except that where a variable would normally be required, an arbitrary
destructuring pattern is allowed. Note that in case of ambiguity,
lambda list syntax is preferred over destructuring syntax. Thus, after
&optional
a list of elements is a list of a destructuring pattern
and a default value form.
The detailed behavior of each lambda list keyword in a lambda-list-directed destructuring pattern is as follows:
&optional
Each following element is a variable or a list of a destructuring
pattern, a default value form, and a supplied-p variable. The default value and
the supplied-p variable can be omitted.
If the list being destructured ends
early, so that it does not have an element to match against this destructuring
(sub)-pattern, the default form is evaluated and destructured instead. The
supplied-p variable receives the value
nil
if the default form is used, t
otherwise.
&rest
, &body
The next element is a destructuring pattern that matches the
rest of the list. &body
is identical to &rest
but declares that what
is being matched is a list of forms that constitutes the body of form.
This next element must be the last unless a lambda list keyword follows it.
&aux
The remaining elements are not destructuring patterns at all, but are
auxiliary variable bindings.
&whole
The next element is a destructuring pattern that matches the entire
form in a macro, or the entire subexpression at inner levels.
&key
Each following element is one of
The rest of the list being destructured
is taken to be alternating keywords and values and is taken apart appropriately.
&allow-other-keys
Stands by itself.