Clojure

Subvecs of primitive vectors cannot be reduced

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Completed
  • Affects Version/s: None
  • Fix Version/s: Release 1.6
  • Component/s: None
  • Labels:
  • Environment:
    1.7.0-08, OS X 10.8
  • Patch:
    Code and Test
  • Approval:
    Ok

Description

Reduce doesn't work on subvecs of primitive vectors.

(let [prim-vec (into (vector-of :long) (range 10000))]
  (reduce + (subvec prim-vec 1 500)))

->> ClassCastException clojure.core.Vec cannot be cast to clojure.lang.PersistentVector  clojure.lang.APersistentVector$SubVector.iterator (APersistentVector.java:523)

If reduce on a subvec doesn't work then neither will nice ops like fold.

Cause: RT.subvec() creates an APersistentVector$SubVector. SubVector.iterator() assumes the source vector is a PersistentVector, however a primitive vector is a Vec (which is not a PersistentVector). This causes a class cast exception as observed on any attempt to iterate over the subvector.

Approach:
1. Provide a generic ranged iterator for APersistentVector, that can be used by SubVector
2. Make the iterator() method for APersistentVector$SubVector use this new iterator where possible (i.e. whenever the source vector is an APersistentVector). If not, the generic super.iterator() method is used (which is slower, but safe for any source vector that implements IPersistentVector)

Patch: clj-1082-patch-v3.diff

Screened by: Alex Miller

  1. clj-1082.patch
    20/Jan/13 6:42 PM
    4 kB
    Mike Anderson
  2. clj-1082-patch-v2.diff
    22/Oct/13 9:08 AM
    4 kB
    Alex Miller
  3. clj-1082-patch-v2.txt
    05/Sep/13 6:12 PM
    4 kB
    Andy Fingerhut
  4. clj-1082-patch-v3.diff
    24/Nov/13 2:15 PM
    3 kB
    Alex Miller

Activity

People

Vote (0)
Watch (3)

Dates

  • Created:
    Updated:
    Resolved: