Special Operator SYMBOL-MACROLET
symbol-macrolet
((symbol expansion)*) declaration* form*
=> result*
symbol - シンボル
expansion - フォーム
declaration - 宣言式。評価されません。
form - 暗黙のprogn
result - formの返却値
symbol-macrolet
は、シンボルsymbolに影響を与える マクロ展開環境の仕組みを提供します。
symbol-macrolet
は、 symbolという名前の各シンボルマクロの 展開関数をレキシカルに確立します。
シンボルマクロの展開関数は、 ただフォームと環境が適用されたときに 正しい展開を返すことが保証されています。 (特に展開が概念的に、展開関数か環境かその両方かの、 どこに保存されるのかは実装依存です)
symbol-macrolet
のキシカルスコープ内で、 変数として参照される各symbolは、 通常のマクロ展開処理が行われます。 3.1.2.1.1. フォームとしてのシンボルをご確認ください。 シンボルマクロの展開は、通常のマクロと同様に、 シンボルマクロの参照先と同じレキシカル環境において、 さらにマクロ展開が行われます。
declarationは、ひとつの例外を除いて 正確にlet
と同じものが許されます。 例外は、symbol-macrolet
のシンボルの定義に special
宣言があったときはエラーが発生します。
symbol-macrolet
のform内で展開が行われるとき、 setq
を使ってsymbolに値をセットしたときは、 それはsetf
を使ったかのように扱われます。 psetq
でのsymbolは、psetf
のように扱われ、 multiple-value-setq
はsetf
のvalues
のように扱われます。
symbol-macrolet
の使用は、 let
によってシャドウされます。 言い換えると、symbol-macrolet
は、 symbolがレキシカルスコープの束縛で囲まれているformにおいてのみ、 symbolの出現が置き換えられます。
;;; 例文は下記と等しいのであり、
;;; (list 'foo (let ((x 'bar)) x)),
;;; 次と等しいのではありません。
;;; (list 'foo (let (('foo 'bar)) 'foo))
symbol-macrolet ((x 'foo))
(list x (let ((x 'bar)) x)))
(=> (foo bar)
NOT=> (foo foo)
symbol-macrolet ((x '(foo x)))
(list x))
(=> ((FOO X))
なし。
グローバル変数として定義されているシンボルに束縛をしようとしたときは、 型program-error
のエラーが発生します。
declarationにsymbol-macrolet
で束縛するシンボル名の special
宣言が含まれていたときは、 型program-error
のエラーが発生します。
特殊フォームであるsymbol-macrolet
の基本的な仕組みは、 with-slots
の実装に使用されています。
symbol-macrolet
フォームがトップレベルフォームであるとき、 formもまたトップレベルフォームとして処理されます。 3.2.3. ファイルのコンパイルをご確認ください。