(defmacro defcache
[type-name fields & specifics]
(let [[base & _] fields
base-field (with-meta base {:tag 'clojure.lang.IPersistentMap})]
`(deftype ~type-name [~@fields]
~@specifics
clojure.lang.ILookup
(valAt [this# key#]
(lookup this# key#))
(valAt [this# key# not-found#]
(if (has? this# key#)
(lookup this# key#)
not-found#))
java.lang.Iterable
(iterator [_#]
(.iterator ~base-field))
clojure.lang.IPersistentMap
(assoc [this# k# v#]
(miss this# k# v#))
(without [this# k#]
(evict this# k#))
clojure.lang.Associative
(containsKey [this# k#]
(has? this# k#))
(entryAt [this# k#]
(when (has? this# k#)
(clojure.lang.MapEntry. k# (lookup this# k#))))
clojure.lang.Counted
(count [this#]
(count ~base-field))
clojure.lang.IPersistentCollection
(cons [this# elem#]
(seed this# (conj ~base-field elem#)))
(empty [this#]
(seed this# (empty ~base-field)))
(equiv [this# other#]
(= other# ~base-field))
clojure.lang.Seqable
(seq [_#]
(seq ~base-field)))))