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.