Skip to content

Instantly share code, notes, and snippets.

@arohner
Created April 23, 2010 19:35
Show Gist options
  • Select an option

  • Save arohner/377054 to your computer and use it in GitHub Desktop.

Select an option

Save arohner/377054 to your computer and use it in GitHub Desktop.
(defmacro decompose-defn-args
"interprets args the way defn would, returns a map that can be consumed by defn-map"
[& args]
`(letfn [(parse-name# [args#]
(println "parse-name: args=" args#)
(assert (symbol? (first args#)))
[(first args#) (rest args#)])
(parse-doc-string# [args#]
(if (string? (first args#))
[(first args#) (rest args#)]
[nil args#]))
(parse-attr-map# [args#]
(if (map? (first args#))
[(first args#) (rest args#)]
[nil args#]))
(parse-params# [args#]
(if (vector? (first args#))
[(first args#) (rest args#)]
[nil args#]))
(parse-body# [args#]
[args# nil])]
(let [args# (quote ~args)
[name# args#] (parse-name# args#)
[doc-string# args#] (parse-doc-string# args#)
[attr-map# args#] (parse-attr-map# args#)
[params# args#] (parse-params# args#)
[body# args#] (parse-body# args#)]
{:name name#
:doc-string doc-string#
:attr-map attr-map#
:params params#
:body body#})))
(defmacro defn-map
"generates a defn expression, but arguments are a map, to make it easier on macro writers. Valid keys: name, doc-string, attr-map, params, body. If params is nil, then body is a multi-arity expression, ([params] body)+ "
[arg-map]
(let [defn-args (filter identity ((juxt :name :doc-string :attr-map :params :body) arg-map))]
`(defn ~@defn-args)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment