2016-12-01 5 views
1

Я экспериментировал с clojure.spec, и я думал, что я хотел бы написать макрос, чтобы сэкономить утомительной набрав :-)clojure: как передать пространство имен в качестве параметра макроса?

Я пытаюсь сделать это:

(defmacro nup 
    [pns pname punit] 
    `(s/def :~pns/name (s/and #(string? %) #(= % ~pname))) 
    `(s/def :~pns/unit (s/and #(string? %) #(= % ~punit)))) 

Я пытался несколько но я не могу сделать замену пространства имен. Есть идеи? Излишне говорить, что макросы не моя сильная сторона.

+0

Вам не нужен макрос для любого из этого, просто выполните 's/def' в функции. – ClojureMostly

ответ

1

Там вы идете:

(defmacro nup 
    [pns pname punit] 
    `(do 
    (s/def ~(keyword (str pns) "name") (s/and #(string? %) #(= % ~pname))) 
    (s/def ~(keyword (str pns) "unit") (s/and #(string? %) #(= % ~punit))))) 

(macroexpand-1 
    '(nup ab :foo :bar)) 

Но s/def просто регистрирует ключевое слово в реестре спецификации в. Так что вам совсем не нужен макрос. Просто используйте функцию намного проще.