2013-09-05 17 views
5

Il Common Lisp Hyperspec afferma "I moduli macro non possono espandersi in dichiarazioni, le espressioni devono apparire come sottoespressioni effettive del modulo a cui si riferiscono."L'espansione macro può contenere (dichiarare ...) espressioni?

Sono confuso sul significato di "espandersi". Una macro come il seguente non funziona per ovvi motivi:

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

Ma cosa succede se la macro di espansione solo contiene un (declare ...) espressione?

(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)) 

Si tratta di una violazione delle specifiche? L'implementazione CL che utilizzo, SBCL, non si lamenta, e infatti la macro sopra sembra funzionare esattamente come previsto. Cosa dà?

risposta

13

Il tuo primo esempio è esattamente ciò che sta proibendo. Non si potrebbe avere il codice come quello in combinazione con qualcosa di simile:

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

volte vedo il codice come questo, però:

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

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

Così, quando la specifica vieta le chiamate macro da "espandere [ing] in dichiarazioni ", si tratta solo di espansioni _immediate_ (non riesco a pensare a una parola migliore)? – nbtrap

+3

Sì, questo è ciò che significa. – Xach

+1

E l'autore del libro "Let Over Lambda" suggerisce di definire macro di lettori che si espandono per dichiarare i moduli, poiché le macro dei lettori vengono espanse prima dell'espansione dei normali macro. – BreakDS