Skip to content

Instantly share code, notes, and snippets.

@francoisdevlin
Created August 12, 2010 20:11
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 francoisdevlin/521634 to your computer and use it in GitHub Desktop.
Save francoisdevlin/521634 to your computer and use it in GitHub Desktop.
(in-ns 'clojure.core)
(defrecord PIP [:protocol :impl])
(defn pip? [x] (instance? clojure.core.PIP x))
(defn extract-pair [p m]
(if (pip? p)
[(:protocol p) (merge (:impl p) m)]
[p m]))
(defn pip [p m]
(if (or (protocol? p) (pip? p))
(let [[extracted-p extracted-m] (extract-pair p m)]
(PIP. extracted-p extracted-m))
(throw (Exception. "Protocol not provided"))))
(defn merge-pip
[& pips]
(let [pips (map #(pip % {}) pips)]
(if (not (apply = (map :protocol pips)))
(throw (Exception. "Trying to merge different protocols."))
(pip (:protocol (first pips)) (apply merge (map :impl pips))))))
(defmacro extend+ [atype & proto+maps]
`(extend ~atype
~(apply concat
(map extract-pair
(partition 2 proto+maps)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment