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-macroletis always lexically scoped. Thecl-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)A
setqof 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
letorlet*binding a symbol macro is treated like acl-letforcl-letf*. This differs from true Common Lisp, where the rules of lexical scoping cause aletbinding to shadow asymbol-macroletbinding. In this package, such shadowing does not occur, even whenlexical-bindingist. (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-letandlexical-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 ofcl-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 todolist(see Iteration) except that the variablexbecomes a true reference onto the elements of the list. Themy-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 nonstandardin-refloop clause that works much likemy-dolist.