A Clojure macro that builds a higher order function from a function

I am trying to write a macro that creates a middleware similar to that used in compojure.

I want to be able to call:

(def-middleware plus-two [x]
  (+ 2 x))

And the result is:

(defn plus-two [f]
 (fn [x]
   (f (+ 2 x)))

I am so far from reading online manuals, but this does not work for me:

(defmacro def-middleware [fn-name args & body]
  '(defn ~fn-name [f]
     (fn ~args
       (f ~@body))))

Any help or pointer to the best macro writing guide would be great, thanks.

+5
source share
2 answers

Let's see what gives us macroexpand-1:

user=> (clojure.pprint/pprint (macroexpand-1 '(def-middleware plus-two [x] (+ 2 x))))
(defn
~fn-name
[f]
$
(fn ~args$ (f (clojure.core/unquote-splicing body))))

, ! -, , , "` ( quasiquote/syntax-quote), " ". , , , , clojure gensym . , ( [f#], not [f]$), . args. :

user=> (defmacro def-middleware [fn-name args & body] `(defn ~fn-name [f#] (fn ~args (f# ~@body))))
#'user/def-middleware
user=> (clojure.pprint/pprint (macroexpand-1 '(def-middleware plus-two [x] (+ 2 x))))
(clojure.core/defn
 plus-two
 [f__594__auto__]
 (clojure.core/fn [x] (f__594__auto__ (+ 2 x))))
nil
user=> 
+8

, , - , . , (f (+ 2 x)) (+ 2 (f x))? , . - , ; .

+3

All Articles