Skip to content

Instantly share code, notes, and snippets.

@didibus
Last active November 3, 2018 09:22
Show Gist options
  • Save didibus/3f51d2168635858c8a0854d25689bf9a to your computer and use it in GitHub Desktop.
Save didibus/3f51d2168635858c8a0854d25689bf9a to your computer and use it in GitHub Desktop.
Clojure macro to define strict keyword argument functions
(defmacro defnk
[name & fdecl]
(let [doc-string? (when (string? (first fdecl))
(first fdecl))
fdecl (if (string? (first fdecl))
(next fdecl)
fdecl)
attr-map? (when (map? (first fdecl))
(first fdecl))
fdecl (if (map? (first fdecl))
(next fdecl)
fdecl)
params (first fdecl)
m (gensym)
params* [{:keys params :as m}]
fdecl (next fdecl)
prepost-map? (if (map? (first fdecl))
(first fdecl)
{})
fdecl (if (map? (first fdecl))
(next fdecl)
fdecl)
body fdecl]
`(defn ~name
~@(if doc-string? [doc-string?] [])
~@(if attr-map? [attr-map?] [])
~params*
~(merge-with (comp vec concat)
prepost-map?
{:pre [`(every? some? ~params)
`(= ~(count params) (count ~m))]})
~@body)))
@didibus
Copy link
Author

didibus commented Nov 3, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment