Greetings,
I'm confused by the failure of 2 record instances to compare as equal, only when generated by a protocol method and having extra fields.
The code below shows this, with uninformative REPL responses snipped. The attached file has similar code as a clojure.test.
Would somebody please help me understand the underlying mechanism. I'll need to develop a workaround to avoid confounding library users.
Thanks, Greg
user=> ;;; Set up protocol and records
user=> (defprotocol FooBar (clone [this]) (switch [this]))
user=> (defrecord Foo [])
user=> (defrecord Bar [])
user=> (extend-type Foo FooBar (clone [this] (map->Foo this)) (switch [this] (map->Bar this)))
user=> (extend-type Bar FooBar (clone [this] (map->Bar this)) (switch [this] (map->Foo this)))
user=> ;;; Create 4 (.equal) instances of Bar, no fields; all works as expected
user=> (def foo0 (->Foo))
user=> (def bar0 (->Bar))
user=> (def bar1 (->Bar))
user=> (def bar-switch-foo0 (switch foo0))
user=> (def bar-clone-bar0 (clone bar0))
user=> bar0
#user.Bar{}
user=> bar1
#user.Bar{}
user=> bar-switch-foo0
#user.Bar{}
user=> bar-clone-bar0
#user.Bar{}
user=> (= bar0 bar1) ; gets expected true
true
user=> (= bar0 bar-switch-foo0) ; gets expected true
true
user=> (= bar0 bar-clone-bar0) ; gets expected true
true
user=> ;;; Create 4 (.equal) instances of Bar with an added field; unexpected results
user=> (def x-foo0 (map->Foo {:field "xtra"}))
user=> (def x-bar0 (map->Bar {:field "xtra"}))
user=> (def x-bar1 (map->Bar {:field "xtra"}))
user=> (def bar-switch-x-foo0 (switch x-foo0))
user=> (def bar-clone-x-bar0 (clone x-bar0))
user=> x-bar0
#user.Bar{:field "xtra"}
user=> x-bar1
#user.Bar{:field "xtra"}
user=> bar-switch-x-foo0
#user.Bar{:field "xtra"}
user=> bar-clone-x-bar0
#user.Bar{:field "xtra"}
user=> (= x-bar0 x-bar1) ; gets expected true
true
user=> (= x-bar0 bar-switch-x-foo0) ; gets UNEXPECTED
false
user=> (= x-bar0 bar-clone-x-bar0) ; gets UNEXPECTED
false
user=> (= bar-switch-x-foo0 bar-clone-x-bar0) ; gets UNEXPECTED
false
user=> (.equals x-bar0 bar-switch-x-foo0) ; .equals is true
true
user=> (.equals x-bar0 bar-clone-x-bar0) ; .equals is true
true
user=> (.equals bar-switch-x-foo0 bar-clone-x-bar0) ; .equals is true
true