Skip to content

Instantly share code, notes, and snippets.

@sunilnandihalli
Created December 17, 2010 20:33
Show Gist options
  • Star 21 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save sunilnandihalli/745654 to your computer and use it in GitHub Desktop.
Save sunilnandihalli/745654 to your computer and use it in GitHub Desktop.
a macro to create fixed-arity curryable function in clojure
(defmacro def-curry-fn [name args & body]
{:pre [(not-any? #{'&} args)]}
(if (empty? args)
`(defn ~name ~args ~@body)
(let [rec-funcs (reduce (fn [l v]
`(letfn [(helper#
([] helper#)
([x#] (let [~v x#] ~l))
([x# & rest#] (let [~v x#]
(apply (helper# x#) rest#))))]
helper#))
`(do ~@body) (reverse args))]
`(defn ~name [& args#]
(let [helper# ~rec-funcs]
(apply helper# args#))))))
#_(def-curry-fn h [x y z]
(+ x y z))
#_((h 1 2) 3) => 6
#_((((h) 1) 2) 3) => 6
#_(def-curry-fn ggg [x y]
[x y])
#_(ggg)
#_((ggg :hello) :hgg) => [:hello :hgg]
#_(ggg :h :hgg) => [:h :hgg]
#_(def-curry-fn f [{:keys [x y] :as w} [a b & d :as e]]
[x y w a b d e])
#_((f {:x 10 :y 20 :z 30}) [1 :b 'c :e 3.0]) => [10 20 {:x 10 :y 20 :z 30} 1 :b (c :e 3.0) [1 :b c :e 3.0]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment