2009-07-06 13 views
7

Próbuję utworzyć funkcję do utworzenia nowej bazy z inną strukturą jako bazą, a jako początek spróbowałem stworzyć makro, które utworzyłoby nową strukturę z tymi samymi polami, co stara. Makro mam co uważałem powinny to jest poniżej, ale to daje następujący błąd:Problem makro Clojure

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

makro:

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

Przykład zastosowania:

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

Żądaną mocą wyjściową w tym przypadku będzie

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

Jestem nowy na clojure, ale znalazłem ten link: http://osdir.com/ml/java.clojure.user/2008-03/msg00108.html – seth

+0

czy można dodać żądane wyjście do przykładu użycia –

Odpowiedz

8

Link seth zamieszczony jako komentarz do Twojego pytania zawiera odpowiedź (winowajcą jest sposób postępowania z argumentami funkcji anonimowych); dodaje się, używając argumentu gensym, powinno działać:

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

Oto ustalona wersja:

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

Dlaczego to trzeba być makro? Funkcja działa również:

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

Dlaczego chcesz skopiować strukturę? Struktury są niezmienne, więc ich kopiowanie nie jest użyteczne. Funkcja ta działa tak samo, jak ten powyżej:

(defn prototype [structure obj] obj) 

Jeśli chcesz stworzyć nową strukturę przy użyciu dodatkowych klawiszy & wartości, wykorzystać assoc.

2

Nie należy stosować #() wewnątrz makra.

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

Nie, że forma fn* ma namespace wykwalifikowanych symbol w jego liście parametrów. To błąd, który dostaję. Należy unikać tego rodzaju specjalnej składni czytnika w makrach i używać zamiast tego długich formularzy.

Powiązane problemy