如何讓Clojure宏充當函數,所以我可以將其作爲參數傳遞給它?我希望不得不以某種方式包裝它。將Clojure宏看作函數
我不希望包裝版本的行爲與原始宏完全一樣(名稱與值的調用不同),但在少數情況下這很重要。
如何讓Clojure宏充當函數,所以我可以將其作爲參數傳遞給它?我希望不得不以某種方式包裝它。將Clojure宏看作函數
我不希望包裝版本的行爲與原始宏完全一樣(名稱與值的調用不同),但在少數情況下這很重要。
如果我正確理解你,你可以把它包裝在一個函數。
考慮這個(傻)實現平方功能的宏:
(defmacro square [x]
(list * x x))
直接把它當作一個ARG將無法正常工作,如你所知:
user=> (map square [1 2 3 4 5])
java.lang.Exception: Can't take value of a macro: #'user/square (NO_SOURCE_FILE:8)
但其包裝在一個函數將做的伎倆:
user=> (map #(square %) [1 2 3 4 5])
(1 4 9 16 25)
或者(更惡意地),你可以做另一個宏做一個更通用的包裝:
(defmacro make-fn [m]
`(fn [& args#]
(eval `(~'~m [email protected]#))))
user=> (map (make-fn square) [1 2 3 4 5])
(1 4 9 16 25)
我會堅持正常的功能包裝,並跳過這最後的黑客! :)
有一個危險的,不推薦使用的宏,你不應該使用它。 :-P
http://clojure.github.com/clojure-contrib/apply-macro-api.html
嗯,這給了我一個堆棧溢出,當我試圖用Clojure 1.2這個例子:(?應用宏或[真虛假])) – pauldoo 2011-04-05 07:50:36
唉這是真的,問題是私有函數價差apply-macro ns:它是一個陳舊clojure.core的副本,如果你用實際版本替換它[黑客工程](https://gist.github.com/986321) – jneira 2011-05-23 06:29:39
diff是好奇的rest [1]) - >(),(next [1]) - > nil。第一個與零?作爲防止謂詞停止遞歸引發了stackoverflow。 – jneira 2011-05-23 06:32:16
對於瘋狂的宏make-fn,下面的那個怎麼樣? 它應該工作得很好,並且希望更容易理解。
(defmacro make-fn [m]
`(fn [& args#]
(eval
(cons '~m args#))))
嗯,這不適用於可變宏: user =>(應用#(或%)[true false false]) java.lang.IllegalArgumentException:錯誤的參數數量(3)傳遞給:user $ eval3 $ fn(NO_SOURCE_FILE:0) – pauldoo 2011-04-05 07:32:18
3分:(1)解決這個例子的最好方法是'(某種身份[true false false])',(2)如果你知道params的數量並且明確表示它, (應用#(或%1%2%3)[true false false]),(3)hacky'make-fn'工作:'(apply(make-fn or)[true false假])' – trptcolin 2011-04-05 13:06:20