I wish to create an abstraction which represents a database table, but which can be accessed using all the usual Clojure seq and conj and all that fancy stuff. Is there a protocol I need to add?
Yes. The protocol is defined by the Java interface clojure.lang.ISeq
. You may want to extend clojure.lang.ASeq
which provides an abstract implementation of it.
Here is an example: a seq
abstraction of a resource which is closable and is closed automatically when the seq
ends. (Not rigorously tested)
(deftype CloseableSeq [delegate-seq close-fn]
clojure.lang.ISeq
(next [this]
(if-let [n (next delegate-seq)]
(CloseableSeq. n close-fn)
(.close this)))
(first [this] (if-let [f (first delegate-seq)] f (.close this)))
(more [this] (if-let [n (next this)] n '()))
(cons [this obj] (CloseableSeq. (cons obj delegate-seq) close-fn))
(count [this] (count delegate-seq))
(empty [this] (CloseableSeq. '() close-fn))
(equiv [this obj] (= delegate-seq obj))
clojure.lang.Seqable
(seq [this] this)
java.io.Closeable
(close [this] (close-fn)))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With