Clojure ADT implementation rescued from clojure.contrib