Clojure

operation on the sorted-set fails under certain conditions

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Declined
  • Affects Version/s: Release 1.7
  • Fix Version/s: None
  • Component/s: None
  • Labels:
  • Environment:
    Windows 8.1

Description

Function generates a sequence of prime numbers. Uses a priority queue implemented as a sorted set of vectors [priority val].

On the iteration (x = 10) fails with message:

(defn sieve [[x & t] pq]
  (lazy-seq
    (if (or (empty? pq) (< x (ffirst pq)))
      (cons x (sieve t (conj pq [(* x x) (next (iterate (partial + x) (* x x)))])))
      (sieve t
        (loop [pq pq] (let [[key val :as head] (first pq)]
          (if (= x key) (recur (conj (disj pq head) [(first val) (next val)])) pq) ))))))

(def primes (sieve (iterate inc 2) (sorted-set)))

(take 4 primes)
;; => (2 3 5 7)

(take 5 primes)
ClassCastException clojure.lang.Iterate cannot be cast to java.lang.Comparable  clojure.lang.Util.compare (Util.java:153)

When x = 10 it goes to the (loop ...) section and fails while trying to recur.

Activity

Hide
Alex Miller added a comment -

Sets are unordered (not sequential) and cannot be used with sequential destructuring. You can wrap (seq ) around the conj in the recur if you wish to make it sequential.

Show
Alex Miller added a comment - Sets are unordered (not sequential) and cannot be used with sequential destructuring. You can wrap (seq ) around the conj in the recur if you wish to make it sequential.
Hide
Anton Gladyshevskiy added a comment -

Destructuring is not a subject of this issue. The problem is that the code that have been successfully evaluated several times before fails on the subsequent iteration. I.e. when x is 4, 6, 8, 9 it works fine, but when x = 10 it fails.

Show
Anton Gladyshevskiy added a comment - Destructuring is not a subject of this issue. The problem is that the code that have been successfully evaluated several times before fails on the subsequent iteration. I.e. when x is 4, 6, 8, 9 it works fine, but when x = 10 it fails.
Hide
Alex Miller added a comment -

Oh, yeah! I totally misread this one after reading the last one. The issue here is that you're trying to put something into a sorted set, but the type of the item (here the sequence produced by `iterate`) is not comparable to the existing items in the set (vectors). Vectors are comparable, but not general sequences.

A simpler example of the same issue is: `(conj (sorted-set) [1] '(2))`

There is a ticket for making lists comparable (CLJ-1467), but I'm not sure it would be a good idea to generically extend this to all sequential data types.

Show
Alex Miller added a comment - Oh, yeah! I totally misread this one after reading the last one. The issue here is that you're trying to put something into a sorted set, but the type of the item (here the sequence produced by `iterate`) is not comparable to the existing items in the set (vectors). Vectors are comparable, but not general sequences. A simpler example of the same issue is: `(conj (sorted-set) [1] '(2))` There is a ticket for making lists comparable (CLJ-1467), but I'm not sure it would be a good idea to generically extend this to all sequential data types.

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: