How can I cause a Clojure macro to act as a function, so I can pass it as an argument for example? I would expect to have to wrap it somehow.
I would not expect the wrapped version to behave exactly the same as the original macro (differences of call by name vs call by value), but it would be useful in a few cases where this wasn't important.
Threading macros, also known as arrow macros, convert nested function calls into a linear flow of function calls, improving readability. In idiomatic Clojure, pure functions transform immutable data structures into a desired output format.
Many core constructs of Clojure are not, in fact, primitives, but are normal macros. Some macros produce simple combinations of primitive forms. For example, when combines if and do: user=> (macroexpand ' (when (pos?
In idiomatic Clojure, pure functions transform immutable data structures into a desired output format. Consider a function that applies two transformations to a map: transform is an example of a common pattern: it takes a value and applies multiple transformations with each step in the pipeline taking the result of the previous step as its input.
Threading macros, also known as arrow macros, convert nested function calls into a linear flow of function calls, improving readability. In idiomatic Clojure, pure functions transform immutable data structures into a desired output format.
If I'm understanding you correctly, you can just wrap it in a function.
Consider this (silly) implementation of a squaring function as a macro:
(defmacro square [x]
(list * x x))
Passing it directly as an arg won't work, as you know:
user=> (map square [1 2 3 4 5])
java.lang.Exception: Can't take value of a macro: #'user/square (NO_SOURCE_FILE:8)
But wrapping it in a function will do the trick:
user=> (map #(square %) [1 2 3 4 5])
(1 4 9 16 25)
Alternatively (and quite a bit more evil-ly), you could make another macro to do a more generic wrapping:
(defmacro make-fn [m]
`(fn [& args#]
(eval `(~'~m ~@args#))))
user=> (map (make-fn square) [1 2 3 4 5])
(1 4 9 16 25)
I'd stick with the normal function wrapping, and skip this last hack! :)
There is a dangerous, deprecated macro that you should not ever use. :-P
http://clojure.github.com/clojure-contrib/apply-macro-api.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With