これらのフォームは局所マクロや“シンボルマクロ”を作る。
このフォームは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ループ節を
定義する。