Create a gist now

Instantly share code, notes, and snippets.

Reify a protocol by giving a generic implementation function that will be called for all protocol methods. Like a proxy.
(ns reify-generic
"reify a protocol such that every method is delegated to a specified method")
(defmacro reify-generic
"Reify the given protocols. Every method of any protocol is implemented such
that f is called as (apply f protocol-method args)
Example:
(defprotocol Calculator
(add [this x y])
(sub [this x y])
(mul [this x y])
(div [this x y]))
(defn test-run []
(let [printer (reify-generic (fn [method this & args] (apply println method args)) Calculator)]
(add printer 1 2)
(sub printer 1 3)))
"
[f & protocols]
`(reify
~@(apply seq (map (fn [proto]
(apply concat [proto]
(map (fn [{name :name arglists :arglists}]
(map (fn [arglist] `(~name ~arglist (~f ~(keyword name) ~@arglist)))
arglists))
(-> proto resolve deref :sigs vals))))
protocols))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment