I found the behavior of Clojure confusing regarding equality between maps and records. In this first example, we have two different types which are structurally equal. The equality = function returns true:
user> (defn make-one-map
[]
{:a "a" :b "b"})
#'user/make-one-map
user> (def m1 (make-one-map))
#'user/m1
user> m1
{:a "a", :b "b"}
user> (def m2 {:a "a" :b "b"})
#'user/m2
user> m2
{:a "a", :b "b"}
user> (= m1 m2)
true
user> (type m1)
clojure.lang.PersistentArrayMap
user> (type m2)
clojure.lang.PersistentHashMap
In the second example we have a hashmap and a record which are structurally equivalent but the = function returns false:
user> (defrecord Titi [a b])
user.Titi
user> (def titi (Titi. 1 2))
#'user/titi
user> titi
#user.Titi{:a 1, :b 2}
user> (= titi {:a 1 :b 2})
false
Why are the differences? I’m using Clojure 1.3 and I found them really confusing.
From the docstring for
defrecord:So, when using
=, type is taken into account. You could use.equalsinstead: