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 to
cl-defmacro(i.e., a macro name, argument list, and macro-expander forms). The macro is defined accordingly for use within the body of the
Because of the nature of macros,
cl-macroletis always lexically scoped. The
cl-macroletbinding 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)
setqof a symbol macro is treated the same as a
(setq foo 4)in the above would be equivalent to
(setf foo 4), which in turn expands to
(setf (car bar) 4).
let*binding a symbol macro is treated like a
cl-letf*. This differs from true Common Lisp, where the rules of lexical scoping cause a
letbinding to shadow a
symbol-macroletbinding. In this package, such shadowing does not occur, even when
t. (This behavior predates the addition of lexical binding to Emacs Lisp, and may change in future to respect
lexical-binding.) At present in this package, only
lexical-let*will shadow a symbol macro. See Obsolete Lexical Binding.
There is no analogue of
defmacrofor symbol macros; all symbol macros are local. A typical use of
cl-symbol-macroletis 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-dolistmacro is similar to
dolist(see Iteration) except that the variable
xbecomes a true reference onto the elements of the list. The
my-dolistcall 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-loopmacro. This package defines a nonstandard
in-refloop clause that works much like