Skip to content

Instantly share code, notes, and snippets.

@tomfaulhaber
Created January 10, 2010 06:25
Show Gist options
  • Save tomfaulhaber/273349 to your computer and use it in GitHub Desktop.
Save tomfaulhaber/273349 to your computer and use it in GitHub Desktop.
A chunk of clojure code that allows you to extend a function def with new argument lists
(ns arity)
(defn make-proxy-args [n] (map #(gensym (str "a" (char (+ 48 %)) "-")) (range n)))
(defn make-proxy-decl [old-f-sym n]
(let [proxy-args (make-proxy-args n)]
`([~@proxy-args]
(apply ~old-f-sym ~(apply vector proxy-args)))))
(defn make-varargs-proxy-decl [old-f-sym n]
(let [proxy-args (make-proxy-args n)
rest-arg (gensym 'rest-)]
`([~@proxy-args & ~rest-arg]
(apply ~old-f-sym (concat ~(apply vector proxy-args) ~rest-arg)))))
(defn make-proxy-decls [old-f-sym fdecl]
(let [arg-lists (map first fdecl)
has-vararg? (some #(some #{'&} %) arg-lists)
counts (map count (filter #(not (some #{'&} %)) arg-lists))
max-args (apply max counts)
count-set (set counts)
counts-to-gen (filter #(not (count-set %)) (range (inc max-args)))]
(concat
(map #(make-proxy-decl old-f-sym %) counts-to-gen)
(when-not has-vararg? (list (make-varargs-proxy-decl old-f-sym max-args))))))
(defmacro add-arity [f & bodies]
(let [fdecl (if (vector? (first bodies))
(list bodies)
bodies)
old-f-sym (gensym 'old-f)
proxy-decls (make-proxy-decls old-f-sym fdecl)]
`(let [~old-f-sym ~f]
(alter-var-root
#'~f (constantly
(fn
~@fdecl
~@proxy-decls))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment