6

評価された引数をマクロ フォームに選択的に渡すためのベスト プラクティスは何ですか?

詳しく説明すると、マクロの有用性は、関数形式のデフォルトの評価規則とは異なり、未評価のパラメーターを受け取る機能にあります。ただし、マクロ引数を評価する正当な使用例があります。

不自然な例を考えてみましょう:

(defparameter *func-body* '((print i) (+ i 1)))

次のように定義され*func-body*たマクロの本体として機能できると便利だとします。our-defun

(defmacro our-defun (fun args &body body)
  `(defun ,fun ,args ,@body))

したがって、 の後に、 get(our-defun foo (i) (+ 1 i))と言うことができます。ただし、 を使用すると、 の結果は(つまり、 の値) になります。マクロの引数としての評価を強制できるとよいでしょう。(foo 1)2(our-defun foo (i) *func-body*)(foo 1)((PRINT I) (+ I 1))*func-body**func-body*our-defun

現在、次のように、これを使用compileおよび実行する手法を考えることができます。funcall

(funcall (compile nil `(lambda () (our-defun foo (i) ,@*func-body*))))

その後、意図したとおり、(our-defun 1)1 を出力して を返します。2これを で動作させるケースも考えられますが、スコーピングの特殊性evalから避けたいと思います。eval

これは最初に私の質問につながります.これを行うためのより簡単な方法またはネイティブな方法はありますか?

PS、

あまり工夫されていない例が function(UPDATE-HOOK)にあります。これは 2 つのライブラリ マクロを使用し(ADD-HOOK)(REMOVE-HOOK)そのパラメータを評価する必要があります。ここでは、上記の(funcall (compile nil `(lambda () ...)))手法が使用されます。

(defun update-hook (hook hook-name &optional code)
  (funcall (compile nil `(lambda () (remove-hook ,hook ',hook-name))))
  (unless (null code)
    (compile hook-name `(lambda () ,@code))
    (funcall (compile nil `(lambda () (add-hook ,hook ',hook-name))))))
4

2 に答える 2

6

それは少し混乱しています。マクロは、評価されていないパラメーターを受け取りません。

マクロはソース コードを取得し、そこからソース コードを作成します。また、Lisp のソース コードは実際にはデータとして提供されることも忘れないでください。マクロは、いくつかのフォームを評価し、いくつかのフォームを評価しないコードを作成します。

マクロは、コンパイル システムで動作する必要があります。実行前。コンパイル時。マクロが見るのはソース コードだけで、そこからソース コードを作成します。マクロは、引数を評価するかどうかではなく、コード変換と考えてください。

*func-body*マクロ our-defun への引数としての評価を強制できればいいのですが

それはあまりきれいではありません。*func-body*コンパイルされたシステムでは、実際に有用なバインドがあり、COMPILE TIMEで解決できることを確認する必要があります。

のようなマクロがある場合DEFUN、ソース コードを静的にすることは理にかなっています。ソースコードをフォームに挿入したい場合は、読み取り時にそれを行うのが理にかなっています:

(defun foo (i) #.`(,@*foo*))

しかし、それは私が通常避けたいコードです。

2 つのライブラリ マクロ(ADD-HOOK)および(REMOVE-HOOK)と は、そのパラメーターを評価する必要があります。

なぜマクロADD-HOOKであるべきなのか? REMOVE-HOOK本当の理由がない場合は、単に関数にする必要があります。すでに再利用が困難になっているためです。

何らかの理由でマクロADD-HOOKを作成したい場合は、通常、マクロも必要です。REMOVE-HOOKUPDATE-HOOK

于 2013-03-27T22:56:37.650 に答える
0

マクロに与えるリストの形式は次のとおりです。

(Quote (...))

したがって、実際に必要なリストは、取得したリストの CADR です。

于 2013-04-17T12:37:32.850 に答える