On Nov 6, 8:27 am, "Michael Wood" <
esiot...@gmail.com> wrote:
> Michael Wood <
esiot...@gmail.com>
On Nov 6, 8:27 am, "Michael Wood" <
esiot...@gmail.com> wrote:
If you are just playing or if the class is only used once in your file/
namespace then this is absolutely okay (clojure does this in
boot.clj) :).
Or you type (import '(clojure.lang PersistentHasMap)),
or (ns my-namespace (:import (clojure.lang PersistentHashMap))) on top
of your file.
> > user> (= (class "abc") String)
> > true
> > user> (class {:a 1 :b 2})
> > #=clojure.lang.PersistentHashMap
> > user> (class {})
> > #=clojure.lang.PersistentHashMap
> > user> (= (class {:a 1}) (class {}))
> > false
> > user> (= (class {:a 1}) (class {:b 2}))
> > true
>
> That seems rather strange to me too.
This is a reader optimization. For very short hashmaps (currently 1
element), the clojure reader uses a clojure.lang.PersistentArrayMap
instead of a full fledged HashMap. The reader does this because he
knows that this map ({:a 1}) will only be constructed with one
MapEntry.
user> (= (class (into {} '([:a 1]))) (class {}))
true
Here the reader doesn't see any literal maps and (into {} '([:a 1]))
evals to a PersistentHashMap with one MapEntry.
Multimethods use the isa? function for dispatch, so to dispatch on a
Map type in general, one would use a java.util.Map or a
clojure.lang.IPersistentMap as the dispatch-value.
user> (and (isa? (class {}) java.util.Map) (isa? (class {:a 1})
java.util.Map))
true
There is also a similar optimization for clojure vectors. They are
constructed as c.l.LazilyPersistentVector which is basically a wrapper
arround a java array. Once you conj onto them, they turn into a
c.l.PersistentVector.
user> (let [v [1 2]] [(class v) (class (conj v 3))])
[#=clojure.lang.LazilyPersistentVector
#=clojure.lang.PersistentVector]