You can also create new types that act mostly like Clojure's existing types using deftype and implementing things like IPersistentStack.
I posted code for (among other things) a bounded deque (using a ringbuffer internally) here fairly recently. The one limitation with these things is that they don't print and then read back as the same type via the Clojure reader -- but then you get the same problem with the built-in sorted-set (comes back a normal set) and sorted-map (comes back a normal map) too. The decorator concept using metadata is interesting, though, because it has the potential to overcome that limitation. The protocol functions would have to look for the metadata and then dispatch on something in it; and you'd have to use print-meta to make the metadata survive a round trip through prn and the reader; but it could in principle be done. Something like (defprotocol MyStack (my-pop* [type-marker stack]) (my-peek* [type-marker stack]) (my-push* [type-marker stack obj])) (defn my-pop [stack] (.my-pop* (:type-marker (meta stack)) stack)) (defn my-peek [stack] (.my-peek* (:type-marker (meta stack)) stack)) (defn my-push [stack obj] (.my-push* (:type-marker (meta stack)) stack obj)) (deftype NormalStackMarker [] MyStack (my-pop* [_ stack] (pop stack)) (my-peek* [_ stack] (peek stack)) (my-push* [_ stack obj] (conj stack obj))) (def normal-stack-marker {:type-marker (NormalStackMarker.)}) (defn normal-stack [] (with-meta [] normal-stack-marker)) (deftype BoundedStackMarker [] MyStack (my-pop* [_ stack] (pop stack)) (my-peek* [_ stack] (peek stack)) (my-push* [_ stack obj] (let [limit (:limit (meta stack))] ...))) (def bounded-stack-marker (BoundedStackMarker.)) (defn bounded-stack [capacity] (with-meta [] {:type-marker bounded-stack-marker :limit capacity})) ... or something like this. The prn/reader trip just has to handle a normal vector with metadata, so *print-meta* is the only maybe-unusual step needed to make these round-trip intact. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en