## Macros

A defmacro lambda-list is a lambda-list-like construct that is used as the third element in the `defmacro` form,

    (defmacro name efmacro-lambda-list [declaration | doc-string] {form}*)

The description of defmacro lambda-lists in &Steele84; is quite ambiguous. &ECL; employs the following syntax.

The complete syntax of a defmacro lambda-list is:

    ( [&whole var]
    [&environment var]
    [pseudo-var]
    [&optional {var | ( pseudo-var [initform [pseudo-var]] )}]
    {[{&rest | &body} pseudo-var]
    [&key {var
    | ({var | (keyword pseudo-var)} [initform [pseudo-var]])}*
    [&allow-other-keys]]
    [&aux {var | (pseudo-var [initform])}*]
    | . var }
    )

where pseudo-var is either a symbol or a list of the following form:

    ( {pseudo-var}*
    [&optional {var | (pseudo-var [initform [pseudo-var]])}*]
    {[{&rest | &body} pseudo-var]
    [&key {var | ({var | (keyword pseudo-var)}
    [initform [pseudo-var]])}*
    [&allow-other-keys]]
    [&aux {var | (pseudo-var [initform])}]
    | . var }
    )

The defmacro lambda-list keyword `&whole` may appear only at the top-level, first in the defmacro lambda-list. It is not allowed within pseudo-var. Use of the `&whole` keyword does not affect the processing of the rest of the defmacro lambda-list:

    (defmacro foo (&whole w x y) ...)

and

    (defmacro foo (x y) ...)

both bind the variables `x` and `y` to the second and the third elements, respectively, of macro forms of `foo`.

The defmacro lambda-list keyword `&environment` may appear only at the top-level, first in the defmacro lambda-list if `&whole` is not supplied, or immediately after the variable that follows `&whole`, if `&whole` is supplied. `&environment` is not allowed within pseudo-var. Like `&whole`, use of `&environment` does not affect the processing of the rest of the defmacro lambda-list. If an `&environment` parameter is supplied and if this parameter is not used at all, then the &ECL; compiler will issue a warning. To suppress the warning, just remove the parameter from the defmacro lambda-list, or add an `ignore` declaration.

The defmacro lambda-list keyword `&body` is completely equivalent to the &rest keyword. &ECL; takes no special action for `&body` parameters.

Although useless, &ECL; allows supplied-p parameters to be destructured. This is useless because supplied-p parameters can never be bound to a non-empty list. Our intention is to stick to the specification in the &Steele84; as far as possible, even if it is silly to do so.

Like for ordinary lambda-lists, the interpreter detects invalid arguments to macro expansion functions. When a parameter is destructured, the structure of the corresponding argument is also checked. Such runtime argument checking may or may not be embedded in compiled code, depending on the environment when the code was generated. If the code was generated while the `safety` optimize level is zero (that is, while the value of `(proclamation '(optimize (safety 0)))` is T), then the generated code does not perform argument checking at all. Otherwise, the compiled code does check the validity of arguments.