-
-
Save hiredman/fbade00f1641dbcb62a0feee2964495e to your computer and use it in GitHub Desktop.
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
(defmacro defpoly [n] | |
`(defmulti ~n (let [preds# (atom ())] | |
(with-meta | |
(fn [& args#] | |
(loop [[[p# v#] & ps#] @preds#] | |
(if p# | |
(if (apply p# args#) | |
v# | |
(recur ps#)) | |
(throw (Exception.))))) | |
{:preds preds#})))) | |
(defmacro defpolymethod [n p args body] | |
(let [v (gensym)] | |
`(do | |
(swap! (:preds (meta (.dispatchFn ~n))) | |
conj | |
[~p '~v]) | |
(defmethod ~n '~v ~args ~body)))) | |
;; user=> (defpoly foo) | |
;; nil | |
;; user=> (defpolymethod foo even? [n] [:even n]) | |
;; #object[clojure.lang.MultiFn 0x29fa6b65 "clojure.lang.MultiFn@29fa6b65"] | |
;; user=> (defpolymethod foo odd? [n] [:odd n]) | |
;; #object[clojure.lang.MultiFn 0x29fa6b65 "clojure.lang.MultiFn@29fa6b65"] | |
;; user=> (foo 1) | |
;; [:odd 1] | |
;; user=> (foo 2) | |
;; [:even 2] | |
;; user=> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment