2009-07-06 20 views
7

Estoy tratando de crear una función para crear una nueva base con otra estructura como base, y como un comienzo intenté crear una macro que crearía una nueva estructura con los mismos campos que la anterior. La macro tengo que pensé que debería hacer esto es por debajo de, pero que está dando el siguiente error:Clojure problema macro

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

Ejemplo de uso:

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

la salida deseada, en este caso sería

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

Soy nuevo en clojure pero encontré este enlace: http://osdir.com/ml/java.clojure.user/2008-03/msg00108.html – seth

+0

podría agregar el resultado deseado al ejemplo de uso –

Respuesta

8

el set enlace publicado como un comentario a la pregunta contiene la respuesta (el culpable es el camino argumentos a funciones anónimas se manejan); A continuación, utilizando un argumento gensym, debería funcionar:

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

Aquí hay una versión fija:

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

¿Por qué esta necesidad de ser una macro? Una función también funciona:

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

¿Por qué quiere copiar la estructura? Las estructuras son inmutables por lo copiarlos no es útil. Esta función hace lo mismo que el anterior:

(defn prototype [structure obj] obj) 

Si desea crear una nueva estructura con teclas adicionales & valores, utilice assoc.

2

No use #() dentro de una macro.

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

No es que la forma fn* tiene un símbolo de espacio de nombres en su lista de parámetros. Ese es el error que estás recibiendo. Debe evitar este tipo de sintaxis especial lector en las macros y utilizar las formas largas lugar.

Cuestiones relacionadas