Перебирая аргументы макроса - PullRequest
6 голосов
/ 06 сентября 2011

Я пытаюсь написать макрос в Clojure, который позволяет вычислять ряд простых выражений "def". Я n00b, когда дело доходит до макросов. Идея в том, что

(my-defs y1 1
     y2 "taco")

должно расшириться до

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

Следующий код выполняет это для особого случая двух определений

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

это хорошо, но у меня возникают проблемы с обобщением этого. Я опробовал несколько наивных вещей, включающих циклическое связывание элементов (partition 2 args), но я всегда получал мусор (я знаю, что это не очень специфично, но разнообразие и степень мусора, казалось, слишком велики, чтобы сообщать здесь). Как мне пройтись по этим и оценить мои определения?

P.S. Макрос my-defs - это игрушка. В конце концов, я действительно хочу выполнить небольшой вспомогательный макрос для создания экземпляра мультиметодных экземпляров. В настоящее время у меня есть большие куски кода, которые выглядят как

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

что немного неприглядно. Было бы хорошо, если бы я мог сделать что-то вроде

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

вместо этого.

1 Ответ

5 голосов
/ 06 сентября 2011

Мне кажется, что вы ищете ~ @ macro расширение / unquote

(defmacro defmethods [n & defs] 
   `(do ~@(map (fn [[a1 a2 a3]] 
                   `(def ~n ~a1 ~a2 ~a3)) 
               (partition 3 defs))))
...