2011-09-05 14 views
6

Sto cercando di scrivere una macro in Clojure che consenta la valutazione di una serie di semplici espressioni "def". Sono un n00b quando si tratta di macro. L'idea è cheCiclo di argomenti di macro

(my-defs y1 1 
    y2 "taco") 

dovrebbe espandersi per

(do (def y1 1) (def y2 "taco")) 

Il seguente codice esegue questa operazione per il caso particolare di due defs

(defmacro my-defs 
    [& args] 
    `(do 
    (def ~(first args) ~(second args)) 
    (def ~(nth args 2) ~(nth args 3)))) 

che è bello, ma sto avendo difficoltà generalizzando Questo. Ho provato alcune cose ingenue che coinvolgono il looping attraverso gli elementi degli elementi di (partition 2 args) ma ho sempre avuto spazzatura (lo so che non è molto specifico ma la diversità e l'estensione della spazzatura mi sembra un po 'troppo da riportare qui). Come faccio a riaggiustare questi sono e valutare i miei difetti?

P.S. La macro my-defs è un giocattolo. Quello che voglio davvero realizzare alla fine è una macro helper littel per istanziare un gruppo di istanze multimethod. Attualmente ho grossi pezzi di codice che assomigliano a

(defmethod f [A B] [x] "AB") 
(defmethod f [A A] [x] "AA") 
(defmethod f [C B] [x] "CB") 

che è un po 'sgradevole. Sarebbe bello se potessi fare qualcosa come

(defmethods f 
    [A B] [x] "AB" 
    [A A] [x] "AA" 
    [C B] [x] "CB") 

invece.

risposta

5

Mi sembra che tu stia cercando l'espansione ~ @ macro/unquote.

(defmacro defmethods [n & defs] 
    `(do [email protected](map (fn [[a1 a2 a3]] 
        `(def ~n ~a1 ~a2 ~a3)) 
       (partition 3 defs)))) 
+0

Grazie, ho scritto i miei defmethod ora! –

+1

Penso che questo modello sia più facile da scrivere sia come (cons 'do (per [[xyz] (partition 3 args)] ...) 'o' \ '(do ~ @ (per ...)) \' La mappa rompe il flusso delle cose, e usando un backquote e '~ @' solo per ottenere un contro, il codice appare confuso – amalloy

+0

@amalloy. Grazie per il suggerimento. (Fai ~ @ (per ...)) sembra migliore. –

Problemi correlati