Welcome! Please see the About page for a little more info on how this works.

+4 votes
in Collections by
retagged by

The implementation of equiv() for PersistentVector involves calling .size() on the object to be compared, even when it is a lazy seq.

https://github.com/clojure/clojure/blob/b8132f92f3c3862aa6cdd8a72e4e74802a63f673/src/jvm/clojure/lang/APersistentVector.java#L98

As a result, a predicate such as (= [1] (range)) does not terminate.
More practically, comparing vectors against large partially-realised seqs may cause them to be fully evaluated, where one might reasonably expect = to short circuit to false on the first non-matching element.

Is this an intentional tradeoff for the more common use case where calling .size() on the second arg does not come with a performance cost?

Interestingly, this size comparison is not implemented for Clojure's persistent lists even though they are counted collections, i.e. (= '(1) (range)) terminates.

Thanks to @opqdonut on Clojurians Slack for helping to pinpoint the cause in the Java source.

1 Answer

+1 vote
by
...