CLHS: Special Operator SYMBOL-MACROLET

#

Special Operator SYMBOL-MACROLET

Syntax:

symbol-macrolet ((symbol expansion)*) declaration* form*

=> result*

Arguments and Values:

symbol---a symbol.

expansion---a form.

declaration---a declare expression; not evaluated.

forms---an implicit progn.

results---the values returned by the forms.

Description:

symbol-macrolet provides a mechanism for affecting the macro expansion environment for symbols.

symbol-macrolet lexically establishes expansion functions for each of the symbol macros named by symbols. The only guaranteed property of an expansion function for a symbol macro is that when it is applied to the form and the environment it returns the correct expansion. (In particular, it is implementation-dependent whether the expansion is conceptually stored in the expansion function, the environment, or both.)

Each reference to symbol as a variable within the lexical scope of symbol-macrolet is expanded by the normal macro expansion process; see Section 3.1.2.1.1 (Symbols as Forms). The expansion of a symbol macro is subject to further macro expansion in the same lexical environment as the symbol macro invocation, exactly analogous to normal macros.

Exactly the same declarations are allowed as for let with one exception: symbol-macrolet signals an error if a special declaration names one of the symbols being defined by symbol-macrolet.

When the forms of the symbol-macrolet form are expanded, any use of setq to set the value of one of the specified variables is treated as if it were a setf. psetq of a symbol defined as a symbol macro is treated as if it were a psetf, and multiple-value-setq is treated as if it were a setf of values.

The use of symbol-macrolet can be shadowed by let. In other words, symbol-macrolet only substitutes for occurrences of symbol that would be in the scope of a lexical binding of symbol surrounding the forms.

Examples:

    ;;; The following is equivalent to
    ;;;   (list 'foo (let ((x 'bar)) x)),
    ;;; not
    ;;;   (list 'foo (let (('foo 'bar)) 'foo))
     (symbol-macrolet ((x 'foo))
       (list x (let ((x 'bar)) x)))
    =>  (foo bar)
    NOT=>  (foo foo)

     (symbol-macrolet ((x '(foo x)))
       (list x))
    =>  ((FOO X))

Affected By: None.

Exceptional Situations:

If an attempt is made to bind a symbol that is defined as a global variable, an error of type program-error is signaled.

If declaration contains a special declaration that names one of the symbols being bound by symbol-macrolet, an error of type program-error is signaled.

See Also:

with-slots, macroexpand

Notes:

The special form symbol-macrolet is the basic mechanism that is used to implement with-slots.

If a symbol-macrolet form is a top level form, the forms are also processed as top level forms. See Section 3.2.3 (File Compilation).

The following X3J13 cleanup issues, not part of the specification, apply to this section:

- LISP-SYMBOL-REDEFINITION:MAR89-X3J13
- SYMBOL-MACROS-AND-PROCLAIMED-SPECIALS:SIGNALS-AN-ERROR
- SYMBOL-MACROLET-DECLARE:ALLOW
- SYMBOL-MACROLET-SEMANTICS:SPECIAL-FORM
- DECLS-AND-DOC

Copyright 1996-2005, LispWorks Ltd. All rights reserved.