( #sharpsign)は、ディスパッチ マクロ文字である標準マクロ文字です。別のキャラクターと合成することになっています。( #'sharpsign 単一引用符)の組み合わせは、その後に関数名またはラムダ式が必要であり、 に展開され(function expression)ます。
したがって、#'fooは読み取り時に に展開されます(function foo)。fooが関数の場合、functionそれを評価します。レキシカルスコープでは、またはfooによる fboundである可能性があります。そのようなレキシカル定義がない場合、シンボルの関数からグローバル関数定義を取得しようとします。fletlabels
現在、レキシカルであれグローバルであれ、マクロを表す(function bar)ときにエラーを通知します。ただし、グローバル マクロのマクロ関数を取得するために使用することはできます。存在する場合は、フォームと環境の 2 つの引数の関数です。barmacroletdefmacro(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。実装固有のコード ウォーカーが必要です。