Previous: , Up: 変数束縛   [Contents][Index]


4.3.4 マクロ束縛

これらのフォームは局所マクロや“シンボルマクロ”を作る。

Special Form: macrolet (bindings…) forms…

このフォームはfletと類似しているが、関数の代わりにマクロ 用である。各bindingdefmacro*への引数と同じフォームの リストである(すなわち、マクロ名、引数リスト、そして マクロエクスパンダフォーム)。マクロはmacroletの本体内の使用に 応じて定義される。

マクロの性質のために、macroletはEmacs Lisp内でさえも レキシカルスコープである: macrolet束縛は、おそらく本体の他の マクロの展開後、物理的に本体forms内に現れる呼び出しにのみ 影響する。

Special Form: symbol-macrolet (bindings…) forms…

このフォームはシンボルマクロを作る。それは関数呼び出しよりも 変数参照のように見えるマクロである。各bindingはリスト ‘(var expansion)’である; 本体forms内の varへのすべての参照はexpansionによって置き換えられる。

(setq bar '(5 . 9))
(symbol-macrolet ((foo (car bar)))
  (incf foo))
bar
     ⇒ (6 . 9)

シンボルマクロのsetqsetfと同様に扱われる。すなわち、 上の(setq foo 4)(setf foo 4)と同等であり、今度は (setf (car bar) 4)へ展開する。

同様に、シンボルマクロを束縛するletlet*letfletf*のように扱われる。これは、レキシカルスコープのルールは letの束縛がsymbol-macroletの束縛をシャドウすることを 引き起こすような真のCommon Lispとは異なる。このパッケージでは、 lexical-letlexical-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ループ節を 定義する。