Skip to content

Instantly share code, notes, and snippets.

@bmillare
Forked from ctford/anarchy.clj
Created September 6, 2012 19:17
Show Gist options
  • Save bmillare/3659663 to your computer and use it in GitHub Desktop.
Save bmillare/3659663 to your computer and use it in GitHub Desktop.
Simple system for plural dispatch
(ns dj.plurality)
(defmacro defplural-body [pluralfn-name arg-list & resolver-body]
`(def ~pluralfn-name (let [implementations# ~(if (resolve pluralfn-name)
`(atom (or @(:dj.plurality/implementations (meta ~pluralfn-name))
[]))
`(atom []))]
(with-meta (fn ~pluralfn-name ~(into [] (rest arg-list))
(let [~(first arg-list) @implementations#]
~@resolver-body))
{:dj.plurality/implementations implementations#}))))
(defmacro defplural [pluralfn-name resolver]
`(defplural-body ~pluralfn-name [implementations# & args#]
(~resolver implementations# args#)))
(defn clear-implementations! [plural-fn]
(reset! (:dj.plurality/implementations (meta plural-fn))
[]))
(defn defimplementation [plural-fn implementation]
(swap! (:dj.plurality/implementations (meta plural-fn))
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