Previous: Function Bindings, Up: Variable Bindings [Contents][Index]

#### 4.3.3 Macro Bindings

These forms create local macros and “symbol macros”.

Macro: cl-macrolet (bindings…) forms…

  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 `cl-macrolet`.

  Because of the nature of macros, `cl-macrolet` is always lexically scoped. The `cl-macrolet` binding will affect only calls that appear physically within the body forms, possibly after expansion of other macros in the body.

Macro: cl-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))
      (cl-symbol-macrolet ((foo (car bar)))
        (cl-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 `cl-letf` or `cl-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, such shadowing does not occur, even when `lexical-binding` is `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` and `lexical-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 of `cl-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 to `dolist` (see Iteration) except that the variable `x` becomes a true reference onto the elements of the list. The `my-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 nonstandard `in-ref` loop clause that works much like `my-dolist`.

Previous: Function Bindings, Up: Variable Bindings [Contents][Index]