Previous: Function Bindings, Up: Variable Bindings
These forms create local macros and “symbol macros”.
This form is analogous to
cl-flet
, but for macros instead of functions. Each binding is a list of the same form as the arguments tocl-defmacro
(i.e., a macro name, argument list, and macro-expander forms). The macro is defined accordingly for use within the body of thecl-macrolet
.Because of the nature of macros,
cl-macrolet
is always lexically scoped. Thecl-macrolet
binding will affect only calls that appear physically within the body forms, possibly after expansion of other macros in the body.
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)) (cl-symbol-macrolet ((foo (car bar))) (cl-incf foo)) bar ⇒ (6 . 9)A
setq
of a symbol macro is treated the same as asetf
. 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
orlet*
binding a symbol macro is treated like acl-letf
orcl-letf*
. This differs from true Common Lisp, where the rules of lexical scoping cause alet
binding to shadow asymbol-macrolet
binding. In this package, such shadowing does not occur, even whenlexical-binding
ist
. (This behavior predates the addition of lexical binding to Emacs Lisp, and may change in future to respectlexical-binding
.) At present in this package, onlylexical-let
andlexical-let*
will shadow a symbol macro. See Obsolete Lexical Binding.There is no analogue of
defmacro
for symbol macros; all symbol macros are local. A typical use ofcl-symbol-macrolet
is in the expansion of another macro:(cl-defmacro my-dolist ((x list) &rest body) (let ((var (cl-gensym))) (list 'cl-loop 'for var 'on list 'do (cl-list* 'cl-symbol-macrolet (list (list x (list 'car var))) body)))) (setq mylist '(1 2 3 4)) (my-dolist (x mylist) (cl-incf x)) mylist ⇒ (2 3 4 5)In this example, the
my-dolist
macro is similar todolist
(see Iteration) except that the variablex
becomes a true reference onto the elements of the list. Themy-dolist
call shown here expands to(cl-loop for G1234 on mylist do (cl-symbol-macrolet ((x (car G1234))) (cl-incf x)))which in turn expands to
(cl-loop for G1234 on mylist do (cl-incf (car G1234)))See Loop Facility, for a description of the
cl-loop
macro. This package defines a nonstandardin-ref
loop clause that works much likemy-dolist
.