ファイルのコンパイル時にマクロは展開されますか?


13

コンパイル時に使用するすべてのインスタンスで展開する必要があるマクロがあります。コードベースを通過して各呼び出しを慎重にラップすることなく、これを指定する方法はありますeval-when-compileか?

回答:


13

バイトコンパイラが到達可能なすべてのマクロは、コンパイル中に展開されます。「到達可能」とは、本質的に引用されていないことを意味します。

defuns、defmacros、lambdas の本体は、それらを含むソースファイルがバイトコンパイルされると、すべてバイトコンパイルされます。そのため、引用符(')内にない限り、マクロ内のマクロは展開されます。よくある間違いは、lambdasを引用符で囲むことです。実際、sを引用符で囲むlambdaべきではありません

これはマクロの大きな利点の1つです。よく書かれている限り、ランタイムのパフォーマンスには影響しません。他の利点は、もちろんその力と汎用性です。欠点は、オブジェクトではなく構文を操作していることです。そのため、問題が発生する余地が多くあります。


7

マラバルバがすでに説明したように、マクロはバイトコンパイル中に展開されます。ファイルがコンパイルされていない場合、ファイルのロード時にマクロが展開されます(積極的なマクロ展開)。

ただし、これに依存しないでください。それは非常に悪いスタイルです。通常、マクロを使用するコードが実際にコンパイルされることを期待することはできません。通常、コンパイル中はできるだけ少ないコードを実行する必要があります。特に、他の方法がない場合にのみ、マクロをほとんど使用しないでください。経験則として、構文にのみマクロを使用し、セマンティクス(または機能)には決して使用しないでください。

マクロは漏れやすい抽象化です。それらの拡張は、コンパイル時にターゲットコードにハードコーディングされており、遡って変更することはできません。その後、ターゲットコードは、展開時のマクロの特定の実装依存します。具体的には、マクロ本体で使用されるすべての内部APIに依存します

したがって、マクロに対してコンパイルされたコードを壊すことなく、このAPIやマクロ展開が依存するものを変更することはできません。

機能性のためのマクロのリベラルな使用は、依存性地獄への道を開きます。


マクロを作成または使用する際に留意すべき非常に良い点。
ショーンオールレッド14

「機能のためのマクロのリベラルな使用は、依存性地獄への道を切り開きます。」1週間前まで、package.elにはバグがあり、完全に正当なマクロ依存関係の状況でパッケージのインストールを完全に中断していました。
マラバルバ14

@Malabarba Careが詳細を提供しますか?
lunaryorn 14

@lunaryorn ここに行きます。厄介な小さな問題。
マラバルバ14

1
@lunaryornマクロは危険であることに同意します(賞賛を少なくするために答えを編集します:)が、バグはその特定のインスタンスではないと思います。そのバグには、マクロをまったく含まない他の(悪化の度合いが低い)症状がありました。また、関数の依存関係に問題が発生しました。
マラバルバ14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.