2009-07-06 13 views
7

Sto cercando di creare una funzione per creare un nuovo basewith un'altra struttura come base, e come inizio ho tentato di creare una macro che creerebbe una nuova struttura con gli stessi campi di quella vecchia. La macro che ho che ho pensato dovrebbe fare questo è al di sotto, ma sta dando il seguente errore:Problema macro Clojure

java.lang.Exception: Can't use qualified name as parameter: user/p1__132 

Macro:

(defmacro prototype [structure obj] 
    `(apply struct ~structure (map #(~obj %) (keys ~obj)))) 

Esempio di utilizzo:

(defstruct bintree :data :left :right) 
(def a (struct bintree 3)) 
(prototype bintree a) 

L'output desiderato in questo caso sarebbe

{:data 3 :left nil :right nil} 
+0

Sono nuovo di clojure ma ho trovato questo collegamento: http://osdir.com/ml/java.clojure.user/2008-03/msg00108.html – seth

+0

potresti aggiungere l'output desiderato all'esempio di utilizzo –

risposta

8

Il collegamento seth pubblicato come commento alla domanda contiene la risposta (il colpevole è il modo in cui vengono gestiti gli argomenti per le funzioni anonime); quanto segue, utilizzando un argomento gensym, dovrebbe funzionare:

(defmacro prototype [structure obj] 
    `(apply struct ~structure (map (fn [x#] (~obj x#)) (keys ~obj)))) 
3

Ecco una versione fissa:

(defmacro prototype [structure obj] 
    `(apply struct ~structure (map ~obj (keys ~obj)))) 

Perché questo bisogno di essere una macro? Una funzione lavora troppo:

(defn prototype [structure obj] 
    (apply struct structure (map obj (keys obj)))) 

Perché si vuole copiare la struttura? Le strutture sono immutabili, quindi non è utile copiarle. Questa funzione fa la stessa cosa come quella di cui sopra:

(defn prototype [structure obj] obj) 

Se si desidera creare una nuova struttura con tasti aggiuntivi & valori, utilizzare assoc.

2

Non si deve usare #() all'interno di una macro.

user> (macroexpand-1 `(foo #(bar %) baz)) 
(user/foo (fn* [user/p1__2047] (user/bar user/p1__2047)) user/baz)

Non che la forma fn* ha un simbolo namespace qualificato nella sua lista di parametri. Questo è l'errore che stai ricevendo. Si dovrebbe evitare questo tipo di sintassi di lettore speciale nelle macro e utilizzare invece i moduli lunghi.

Problemi correlati