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. ファイルのコンパイルをご確認ください。