This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-01-31
Channels
- # announcements (22)
- # asami (19)
- # aws-lambda (4)
- # babashka (42)
- # beginners (43)
- # calva (28)
- # cider (1)
- # clerk (79)
- # clj-kondo (12)
- # clojure (47)
- # clojure-berlin (1)
- # clojure-brasil (1)
- # clojure-dev (12)
- # clojure-europe (40)
- # clojure-nl (2)
- # clojure-norway (5)
- # clojure-uk (3)
- # clojurescript (56)
- # clr (12)
- # conjure (8)
- # cursive (4)
- # datomic (78)
- # dev-tooling (6)
- # exercism (1)
- # fulcro (9)
- # hoplon (3)
- # jobs (3)
- # jobs-discuss (4)
- # lambdaisland (3)
- # leiningen (1)
- # london-clojurians (1)
- # lsp (125)
- # malli (32)
- # matcher-combinators (3)
- # nrepl (1)
- # off-topic (6)
- # pathom (39)
- # re-frame (13)
- # releases (2)
- # remote-jobs (3)
- # sci (7)
- # shadow-cljs (117)
- # sql (6)
- # squint (7)
- # tools-build (15)
- # tools-deps (12)
I'm looking at the code for APersistentVector
and there is a piece of code that I am having trouble understanding. I'm comparing doEquals
with doEquiv
. I would expect them to be quite similar, the primary difference being that s as you move through the vector and thing you're comparing against one will use Util.equal
to compare items and the other will use Util.equiv
. Each has three cases: (1) comparing against an IPersistentVector
; (2) comparing against a java.util.List
; (3) otherwise. For cases (1) and (3), indeed they are identical except for Util.equal
vs Util.equiv
. But for case (2), there is a difference. In doEquals
, there is a short-circuit test to get us out early:
Collection ma = (Collection) obj; // obj is what are comparing to, v is IPersistentVector
if(ma.size() != v.count() || ma.hashCode() != v.hashCode())
return false;
In doEquiv
, the short-circuit code is
Collection ma = (Collection) obj;
if((!(ma instanceof IPersistentCollection) || (ma instanceof Counted)) && (ma.size() != v.count()))
return false;
I can understand the hashcode check going away -- more things are 'equiv' than 'equals' and the hashcode consistency will only work for Equals. I read the guard in the doEquiv
code as trying to avoid calling .size()
on an IPersistentCollection
that is not Counted
so that we avoid a potentially costly computation. My question is: why is that guard not on the doEquals
case? What am I missing? (Or is it just missing?)> trying to avoid calling .size()
on an IPersistentCollection
that is not Counted
so that we avoid a potentially costly computation
definitely, yes (specifically infinite seqs, which are very expensive to count ;)
off the top of my head, don't know
That was a fairly recent commit: https://github.com/clojure/clojure/commit/b30a99014814f2fe68833622a567c80133b0c417
oh that rings a bell now. maybe doEquals should have changed similarly
I'll ask Fogus since he worked on that to see if he remembers more
seems likely
I created a jira for that https://clojure.atlassian.net/browse/CLJ-2746