O'Reilly logo

Clojure Programming by Brian Carper, Christophe Grand, Chas Emerick

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Participating in Clojure’s Collection Abstractions

In “Schrödinger’s cat”, we had a glimpse of how to make a custom type participate in one of Clojure’s abstractions by making a type dereferenceable. Let’s raise the bar a bit and work through a complete data structure implementation that is fully integrated into Clojure’s abstractions: namely, an array-backed set, specialized to be more efficient in both performance and memory than standard tree-based hashing sets for very small numbers of items.[209]

Participating in a Clojure abstraction currently means extending certain Java interfaces that Clojure defines for each abstraction. Thus, all of our implementation work must be performed inline.[210]

In general, the most difficult part of participating in Clojure’s abstractions is identifying which interfaces and methods are to be implemented, as such things are largely undocumented officially.[211] A helper function will get us most of the way there, though:

(defn scaffold
  "Given an interface, returns a 'hollow' body suitable for use with `deftype`."
  [interface]
  (doseq [[iface methods] (->> interface
                            .getMethods
                            (map #(vector (.getName (.getDeclaringClass %))
                                    (symbol (.getName %))
                                    (count (.getParameterTypes %))))
                            (group-by first))]
    (println (str "  " iface))
    (doseq [[_ name argcount] methods]
      (println
        (str "    "
          (list name (into '[this] (take argcount (repeatedly gensym)))))))))

By looking at the output of (ancestors (class #{})), we can see that clojure.lang.IPersistentSet is the primary ...

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required