2010-09-21 12 views
7

È possibile scrivere una macro in Clojure che genera più di un valore o espressione? Per me sembra che non sia possibile, almeno non usando il modello di citazione della sintassi `(..).Come si scrive una macro Clojure per creare più di un'espressione?

ad es. da: [1 4] via [1 (mr 2 3) 4] a [1 2 3 4]

o da:

(do 
    (prn 1) 
    (prn 4)) 

via:

(do 
    (prn 1) 
    (mr 2 3) 
    (prn 4)) 

a:

(do 
    (prn 1) 
    (prn 2) 
    (prn 3) 
    (prn 4)) 

risposta

10

Una macro si espande una forma in un'altra forma, in modo da non posso avere un ritorno macro due completamente indipendenti f ORM. Tuttavia, puoi fare in modo che restituisca moduli composti come le dichiarazioni do che fanno un sacco di cose.

(defmacro foo [n] 
    `(do [email protected](map #(list println %) n))) 

Per il vostro esempio di cui sopra è possibile inserire la macro intorno alla forma che si desidera modificare:

(expand-mr 
(do 
    (prn 1) 
    (mr 2 3) 
    (prn 4))) 

macro sono progettati per essere al sicuro e come tali non possono modificare nulla al di fuori della propria scopo. Attualmente una macro ottiene un'espressione s e la trasforma in un'altra espressione s più utile o utile. Affinché una macro restituisca due espressioni s separate, dovrebbe modificare la sua espressione di inclusione. La sintassi dovrebbe essere radicalmente diversa e non sono chiaro come ciò avverrebbe con le espressioni s. La soluzione è espandere l'ambito della macro per includere tutto ciò che deve essere modificato.

+0

Grazie Arthur! Stavo già aspettando quella risposta, ma è bello esserne certi. – Stefan

+0

Ma puoi davvero darmi un esempio di come una macro che restituisce due moduli indipendenti può causare un problema di sicurezza, ma è al sicuro altrimenti? Penso che lo scopo sia sempre lo stesso. – Stefan

+0

Sto usando il termine "sicuro" scusatemi vagamente per quello. Modificherò per espandere su quello. –

Problemi correlati