Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Treating a file of Java floats as a lazy Clojure sequence

Tags:

io

clojure

What would be an ideomatic way in Clojure to get a lazy sequence over a file containing float values serialized from Java? (I've toyed with a with-open approach based on line-reading examples but cannot seem to connect the dots to process the stream as floats.)

Thanks.

like image 548
Cumbayah Avatar asked Jun 02 '10 20:06

Cumbayah


People also ask

What is a lazy sequence Clojure?

Lazy sequences in Clojure have two parts, the head is the first unrealized element of the sequence, and the thunk is an uninvoked, argument-less function that, when called, will realize the rest of the elements in the sequence starting from the head.

Does Clojure have lazy evaluation?

Clojure is not a lazy language. However, Clojure supports lazily evaluated sequences. This means that sequence elements are not available ahead of time and produced as the result of a computation. The computation is performed as needed.

What is a sequence in Clojure?

Clojure defines many algorithms in terms of sequences (seqs). A seq is a logical list, and unlike most Lisps where the list is represented by a concrete, 2-slot structure, Clojure uses the ISeq interface to allow many data structures to provide access to their elements as sequences.


1 Answers

(defn float-seqs [#^java.io.DataInputStream dis]
  (lazy-seq
    (try
      (cons (.readFloat dis) (float-seqs dis))
      (catch java.io.EOFException e
        (.close dis)))))

(with-open [dis (-> file java.io.FileInputStream. java.io.DataInputStream.)]
  (let [s (float-seqs dis)]
    (doseq [f s]
      (println f))))

You are not required to use with-open if you are sure you are going to consume the whole seq.

If you use with-open, double-check that you're not leaking the seq (or a derived seq) outside of its scope.

like image 104
cgrand Avatar answered Oct 02 '22 12:10

cgrand