2011-09-05 64 views
6

我想在Clojure中編寫一個允許評估一系列簡單的「def」表達式的宏。當涉及到宏時,我是一個n00b。這個想法是,循環遍歷宏的參數

(my-defs y1 1 
    y2 "taco") 

應擴大到

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

下面的代碼實現這兩個DEFS

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

,這是很好的特例,但我有麻煩推廣這個。我嘗試了一些天真的事情,涉及通過綁定(partition 2 args)元素的綁定,但我總是得到垃圾(我知道這不是很具體,但垃圾的多樣性和範圍似乎有點太多,無法在這裏報告)。我如何循環這些並評估我的defs?

P.S. 宏my-defs是一個玩具。我最終想要完成的是一個littel助手宏來實例化一堆multimethod實例。目前我有大塊的代碼,看起來像

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

改爲。

回答

5

它在我看來就像你正在尋找〜@宏觀擴張/無法引用。

(defmacro defmethods [n & defs] 
    `(do [email protected](map (fn [[a1 a2 a3]] 
        `(def ~n ~a1 ~a2 ~a3)) 
       (partition 3 defs)))) 
+0

謝謝,我寫了我的defmethods吧! –

+1

我認爲這個模式更容易寫成'(cons'do(for [[xyz](partition 3 args)] ...)'或'\'(do〜@(for ...))' '。Map分解了事物的流向,使用反引號和'〜@'來得到一個缺點使得代碼看起來很混亂 – amalloy

+0

@amalloy。謝謝你的提示。(do〜@(for ...))看起來更好。 –