Treat Clojure macro as a function

后端 未结 3 2004
后悔当初
后悔当初 2021-01-01 18:33

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

相关标签:
3条回答
  • 2021-01-01 19:16

    There is a dangerous, deprecated macro that you should not ever use. :-P

    http://clojure.github.com/clojure-contrib/apply-macro-api.html

    0 讨论(0)
  • 2021-01-01 19:27

    For the crazy macro make-fn, how about the one below? It should work as well, and hopefully easier to understand.

    (defmacro make-fn [m] 
     `(fn [& args#]
        (eval 
          (cons '~m args#))))
    
    0 讨论(0)
  • 2021-01-01 19:30

    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! :)

    0 讨论(0)
提交回复
热议问题