Skip to content

Instantly share code, notes, and snippets.

@ctford
Created September 5, 2012 10:43
Show Gist options
  • Save ctford/3634871 to your computer and use it in GitHub Desktop.
Save ctford/3634871 to your computer and use it in GitHub Desktop.
Simple system for plural dispatch
(ns anarchy.core)
(def plurality {})
(defmacro defplural [method resolver]
`(def ~method (fn ~method [& args#] (~resolver (plurality ~method) args#))))
(defmacro defimplementation [method implementation]
`(def plurality (update-in plurality [~method] #(conj % ~implementation))))
(defplural cumulative (fn [implementations args] (apply (apply comp implementations) args)))
(defimplementation cumulative inc)
(defimplementation cumulative dec)
(cumulative 1)
(defplural clobber (fn [implementations args] (-> implementations peek (apply args))))
(defimplementation clobber inc)
(defimplementation clobber dec)
(clobber 1)
(defplural broadcast (fn [implementations args] (->> implementations (map #(apply % args)) dorun)))
(defimplementation broadcast #(println (str % " is the loneliest number.")))
(defimplementation broadcast #(println (str "All for " %)))
(broadcast 1)
(defplural all (fn [implementations args] (->> implementations (map #(apply % args)) set)))
(defimplementation all #(* % 3))
(defimplementation all #(+ % 3))
(all 1)
(defplural predicate
(fn [implementations args]
(let [match (->> implementations (filter (fn [[pred? implementation]] (apply pred? args))) first)]
(apply match args))))
(defimplementation predicate [even? "Even"])
(defimplementation predicate [odd? "Odd"])
(predicate 1)
(defplural multi
(fn [implementations args]
(let [dispatch identity
implementation ((reduce into implementations) (apply dispatch args))]
(apply implementation args))))
(defimplementation multi {0 (comp inc inc)})
(defimplementation multi {1 (comp dec dec)})
(multi 1)
(defplural random (fn [implementations args] (-> implementations rand-nth (apply args))))
(defimplementation random #(+ % 100))
(defimplementation random #(- % 100))
(random 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment