Looking for common-lisp Answers? Try Ask4KnowledgeBase
Looking for common-lisp Keywords? Try Ask4Keywords

common-lispマクロ


備考

マクロの目的

マクロは、コードの生成、コードの変換、および新しい記法の提供を目的としています。これらの新しい表記法は、ドメインレベルの構造や新しい組み込み言語全体を提供するなど、プログラムをよりよく表現するのに適しています。

マクロはソースコードを自明にすることができますが、デバッグは難しくなります。経験則として、通常の関数ではマクロを使用すべきではありません。それらを使用するときは、通常の落とし穴を避け、よく使われるパターンと命名規則に固執しようとします。

マクロ展開順序

関数と比較すると、マクロは逆の順序で展開されます。最初から最後までつまり、デフォルトでは、外部マクロに必要な構文を生成するために内部マクロを使用することはできません。

評価オーダー

時には、マクロはユーザー提供のフォームを移動する必要があります。評価の順序を変更しないようにする必要があります。ユーザーは、順番に起こっている副作用に頼っている可能性があります。

一度だけ評価する

マクロの展開では、同じユーザー提供フォームの値を複数回使用する必要があります。フォームに副作用が発生したり、高価な機能が呼び出されたりする可能性があります。したがって、マクロはそのようなフォームを一度だけ評価するようにしなければなりません。通常、これはローカル変数( GENSYM edという名前)に値を代入することによって行われます。

EVAL-WHENを使用してマクロで使用される関数

複雑なマクロは、ロジックの一部が別々の機能で実装されることがあります。しかし、実際のコードがコンパイルされる前にマクロが展開されていることを覚えておく必要があります。ファイルをコンパイルするとき、デフォルトでは、同じファイルに定義されている関数と変数は、マクロの実行中は使用できません。マクロによって使用される同じファイル内のすべての関数と変数の定義は、 EVAL-WHEN -formの中にラップされなければなりません。 EVAL-WHENは、ロードと実行時に囲まれたコードも評価する必要がある場合に、3回指定する必要があります。

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defun foobar () ...))

これはマクロの展開から呼び出される関数には当てはまりません。マクロ自体から呼び出される関数にのみ適用されます。

マクロ 関連する例