-
-
Save fogus/3660226 to your computer and use it in GitHub Desktop.
Simple system for plural dispatch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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