これらのフォームは局所マクロや“シンボルマクロ”を作る。
このフォームはflet
と類似しているが、関数の代わりにマクロ
用である。各bindingはdefmacro*
への引数と同じフォームの
リストである(すなわち、マクロ名、引数リスト、そして
マクロエクスパンダフォーム)。マクロはmacrolet
の本体内の使用に
応じて定義される。
マクロの性質のために、macrolet
はEmacs Lisp内でさえも
レキシカルスコープである: macrolet
束縛は、おそらく本体の他の
マクロの展開後、物理的に本体forms内に現れる呼び出しにのみ
影響する。
このフォームはシンボルマクロを作る。それは関数呼び出しよりも 変数参照のように見えるマクロである。各bindingはリスト ‘(var expansion)’である; 本体forms内の varへのすべての参照はexpansionによって置き換えられる。
(setq bar '(5 . 9)) (symbol-macrolet ((foo (car bar))) (incf foo)) bar ⇒ (6 . 9)
シンボルマクロのsetq
はsetf
と同様に扱われる。すなわち、
上の(setq foo 4)
は(setf foo 4)
と同等であり、今度は
(setf (car bar) 4)
へ展開する。
同様に、シンボルマクロを束縛するlet
やlet*
はletf
や
letf*
のように扱われる。これは、レキシカルスコープのルールは
let
の束縛がsymbol-macrolet
の束縛をシャドウすることを
引き起こすような真のCommon Lispとは異なる。このパッケージでは、
lexical-let
やlexical-let*
だけがシンボルマクロを
シャドウする。
シンボルマクロにはdefmacro
に似たものはない; すべての
シンボルマクロは局所的である。symbol-macrolet
の典型的な使用は
他のマクロの展開内である:
(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)
この例では、my-dolist
マクロは変数x
はリストの要素上の真の
参照になる点を除いてdolist
(see 繰り返し)に類似している。
ここで示されたmy-dolist
呼び出しは下記に展開する。
(loop for G1234 on mylist do (symbol-macrolet ((x (car G1234))) (incf x)))
これは今度は下記に展開する。
(loop for G1234 on mylist do (incf (car G1234)))
loop
マクロの記述はSee ループ機能. このパッケージは
my-dolist
とたいへん似た働きをする非標準in-ref
ループ節を
定義する。