Macro Bindings
--------------
These forms create local macros and "symbol macros."
- Special Form: macrolet (bindings...) forms...
This form is analogous to `flet', but for macros instead of
functions. Each BINDING is a list of the same form as the
arguments to `defmacro*' (i.e., a macro name, argument list, and
macro-expander forms). The macro is defined accordingly for use
within the body of the `macrolet'.
Because of the nature of macros, `macrolet' is lexically scoped
even in Emacs Lisp: The `macrolet' binding will affect only calls
that appear physically within the body FORMS, possibly after
expansion of other macros in the body.
- Special Form: symbol-macrolet (bindings...) forms...
This form creates "symbol macros", which are macros that look like
variable references rather than function calls. Each BINDING is a
list `(VAR EXPANSION)'; any reference to VAR within the body FORMS
is replaced by EXPANSION.
(setq bar '(5 . 9))
(symbol-macrolet ((foo (car bar)))
(incf foo))
bar
=> (6 . 9)
A `setq' of a symbol macro is treated the same as a `setf'. I.e.,
`(setq foo 4)' in the above would be equivalent to `(setf foo 4)',
which in turn expands to `(setf (car bar) 4)'.
Likewise, a `let' or `let*' binding a symbol macro is treated like
a `letf' or `letf*'. This differs from true Common Lisp, where
the rules of lexical scoping cause a `let' binding to shadow a
`symbol-macrolet' binding. In this package, only `lexical-let'
and `lexical-let*' will shadow a symbol macro.
There is no analogue of `defmacro' for symbol macros; all symbol
macros are local. A typical use of `symbol-macrolet' is in the
expansion of another macro:
(defmacro* my-dolist ((x list) &rest body)
(let ((var (gensym)))
(list 'loop 'for var 'on list 'do
(list* 'symbol-macrolet (list (list x (list 'car var)))
body))))
(setq mylist '(1 2 3 4))
(my-dolist (x mylist) (incf x))
mylist
=> (2 3 4 5)
In this example, the `my-dolist' macro is similar to `dolist'
(Note:Iteration) except that the variable `x' becomes a true
reference onto the elements of the list. The `my-dolist' call
shown here expands to
(loop for G1234 on mylist do
(symbol-macrolet ((x (car G1234)))
(incf x)))
which in turn expands to
(loop for G1234 on mylist do (incf (car G1234)))
Note:Loop Facility, for a description of the `loop' macro.
This package defines a nonstandard `in-ref' loop clause that works
much like `my-dolist'.