Skip to content

Instantly share code, notes, and snippets.

Created April 20, 2016 12:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/2ab4b4adedc1c35881a96b8871e9f7ab to your computer and use it in GitHub Desktop.
Save anonymous/2ab4b4adedc1c35881a96b8871e9f7ab to your computer and use it in GitHub Desktop.
(defmacro fnp
"A macro for defining functions that take an optional first argument that is a map of parameters"
[& body]
(let [[fn-name & fn-body] (if (symbol? (first body))
body
(cons (gensym "fnp") body))
fn (if-not (->> body flatten (some #(= :- %)))
'fn
'schema/fn)]
`(let [fnp# (~fn ~@body)]
(fn ~fn-name
[& args#]
(if (not (map? (first args#)))
;; If the first argument isn't a map, make it an empty map
(apply fnp# {} args#)
(apply fnp# args#))))))
(defmacro defnp
"A macro for defining functions that take an optional first argument, that is a map of parameters"
[fn-name & body]
(let [metadata (take-while
#(not (or (vector? %) (and (list? %) (-> % first vector?))))
body)
fn-body (drop (count metadata) body)]
`(def ~fn-name
~@metadata
(with-meta
(fnp ~fn-name ~@fn-body)
(meta ~fn-name)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment