Clojure

Unnecessary reflection with `indexOf` on vector

Details

  • Type: Defect Defect
  • Status: Open Open
  • Priority: Minor Minor
  • Resolution: Unresolved
  • Affects Version/s: Release 1.9
  • Fix Version/s: None
  • Component/s: None

Description

This generates a reflection warning:

(let [id-1 3
      id-2 1
      id-3 2
      ids [id-1 id-2 id-3]]
  #(compare (.indexOf ids %1) (.indexOf ids %2)))
;; => call to method indexOf on clojure.lang.IPersistentVector can't be resolved (no such method).

This does not:

(let [ids [3 2 1]]
  #(compare (.indexOf ids %1) (.indexOf ids %2)))

The only difference is whether the elements of the vector are literal, which shouldn't affect the call to indexOf.

Activity

Hide
Alex Miller added a comment - - edited

I believe what's happening here is that in the first case, it gets typed as a PersistentVector (concrete data structure read by the reader). PV implements Collection and so requires no reflection.

In the second case, the vector requires evaluation and its type is IPersistentVector (the interface). IPV does not extend Collection (its independent of that interface) and so it can't find the indexOf method.

Stepping back from both, we're doing Java interop on an object that we are expecting to be a Collection. I'm somewhat on the fence about whether we should expect ids to carry this info when performing interop on it here. Depends how much you think that the abstract Clojure vector collection is a Java collection (vs the implementation of one).

Doesn't seem easily "fixable" to me in ways that are clean.

Show
Alex Miller added a comment - - edited I believe what's happening here is that in the first case, it gets typed as a PersistentVector (concrete data structure read by the reader). PV implements Collection and so requires no reflection. In the second case, the vector requires evaluation and its type is IPersistentVector (the interface). IPV does not extend Collection (its independent of that interface) and so it can't find the indexOf method. Stepping back from both, we're doing Java interop on an object that we are expecting to be a Collection. I'm somewhat on the fence about whether we should expect ids to carry this info when performing interop on it here. Depends how much you think that the abstract Clojure vector collection is a Java collection (vs the implementation of one). Doesn't seem easily "fixable" to me in ways that are clean.

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated: