( #
sharpsign)は、ディスパッチ マクロ文字である標準マクロ文字です。別のキャラクターと合成することになっています。( #'
sharpsign 単一引用符)の組み合わせは、その後に関数名またはラムダ式が必要であり、 に展開され(function expression)
ます。
したがって、#'foo
は読み取り時に に展開されます(function foo)
。foo
が関数の場合、function
それを評価します。レキシカルスコープでは、またはfoo
による fboundである可能性があります。そのようなレキシカル定義がない場合、シンボルの関数からグローバル関数定義を取得しようとします。flet
labels
現在、レキシカルであれグローバルであれ、マクロを表す(function bar)
ときにエラーを通知します。ただし、グローバル マクロのマクロ関数を取得するために使用することはできます。存在する場合は、フォームと環境の 2 つの引数の関数です。bar
macrolet
defmacro
(macro-function 'bar)
bar
のマクロ関数をフォームに適用しない限りbar
、それはおそらくあなたが望むものではありません。のマクロ関数を適用することを考えてみましょうand
: 論理ブール演算は実行されません。おそらく、指定されたフォームがif
.
ただし、これが必要な場合macro-function
は、2 番目のオプションのパラメーターである環境があることに注意してください。defmacro
または の引数として環境を取得できますdefine-setf-expander
。後者の場合、通常get-setf-expansion
、サブフォームを展開する際に字句環境を考慮に入れる必要があります。
これを試してください:
(funcall (macro-function 'and) '(and form1 form2 form3) nil)
演習: 独自のmacroexpand-1
と をmacroexpand
実装します。
演習: Common Lisp の特殊演算子を認識して、サブフォームに再帰するa macroexpand-all
、 aを実装します。macroexpand
注: を使いすぎないでくださいmacroexpand-all
。実装固有のコード ウォーカーが必要です。