3

I'd like to have a version of sequence that doesn't do the chunking of 32 elements. Currently, this code will output

(def peek #(doto % (print " ")))
(def pause #(do (Thread/sleep 10)
                %))

(take 2 (->> (range 100)
             (sequence (comp (map peek)
                             (map pause)
                             (map inc)))))

;; prints 0 1 2 3 4 <..etc..> 32
;; => (0, 1)

I'd like a version of it so that it only iterates through the elements that it needs

(take 2 (->> (range 100)
             (iter-sequence  (comp (map peek)
                             (map pause)
                             (map inc)))))

;; prints 0 1
;; => (0, 1)

Is there a way to do this?

zcaudate
  • 13,998
  • 7
  • 64
  • 124

1 Answers1

3

I had to change a couple of things to get it working. The first is to cut and paste sequence code and replace clojure.lang.RT/chunkIteratorSeq with an alternative version of clojure.lang.IteratorSeq that has exposed public constructor methods.

The reason being is that the clojure.lang.IteratorSeq/create has a check to iter.next() on L27 which will block if the source is blocking.

(defn seqiter
  {:added "1.0"
   :static true}
  ([coll] coll)
  ([xform coll]
   (IteratorSeq.
    (TransformerIterator/create xform (clojure.lang.RT/iter coll))))
  ([xform coll & colls]
   (IteratorSeq.
    (TransformerIterator/createMulti
     xform
     (map #(clojure.lang.RT/iter %) (cons coll colls))))))
zcaudate
  • 13,998
  • 7
  • 64
  • 124
  • the source is here: https://gist.github.com/zcaudate/269d8750b6316166f14be15bfb8aa500#file-iteratorseq-java-L48 – zcaudate Aug 19 '20 at 12:04
  • also, https://github.com/cgrand/xforms/blob/master/src/net/cgrand/xforms.cljc#L555 does the same thing. – zcaudate Aug 20 '20 at 04:29