2013-09-05 13 views
5

Common Lisp Hyperspecは、 "マクロフォームは宣言に展開できません;宣言式は、それらが参照するフォームの実際のサブ式として表示する必要があります。マクロ展開で式を含むことができますか?

私は "expand into"の意味に混乱しています。

(defmacro optimize-fully() 
    `(declare (optimize (speed 3) (safety 0)))) 

しかし、どのような場合、マクロ展開は単なる(declare ...)表現が含まれています。次のようなマクロは、明白な理由のために動作しないのだろうか?

(defmacro defun-optimized (name (&rest lambda-list) &rest body) 
    `(defun ,name ,lambda-list 
     (declare (optimize (speed 3) (safety 0))) 
     ,@body)) 

(defun-optimized foobar (a b) 
    (* a b)) 

これは仕様違反ですか?私が使っているCLの実装であるSBCLは、不平を言っておらず、実際、上記のマクロは、期待通りに正確に動作するようです。何がありますか?

答えて

13

最初の例は、まったく禁止するものです。私は時々しかし、このようなコードを参照してください

(defun optimized (a b) 
    (optimize-fully) 
    (+ a b)) 

(defvar *optimization-settings* '(optimize (speed 3) (safety 0))) 

(defun foo (a b) 
    (declare #.*optimization-settings*) 
    ...) 
+2

に[INGの]だから、スペックは拡張」からマクロ呼び出しを禁止するときは、このようなものと組み合わせることのようなコードを持っていませんでした宣言 "、それは_immediate_(私はより良い言葉を考えることはできません)拡張について話しているだけですか? – nbtrap

+3

はい、そうです。 – Xach

+1

そして、 "Let Over Lambda"という本の著者は、通常のマクロが展開される前にリーダマクロが展開されるので、フォームを宣言するために展開するリーダマクロを定義することを提案しています。 – BreakDS

関連する問題