Understanding futures and doall in Clojure -


i came across example on futures in clojure example

(let [sleep-and-wait          (map (fn [time]            (future              (thread/sleep time)              (println (str "slept " time " sec" ))))                [4000 5000])]      (doall (map deref sleep-and-wait))      (println "done")) 

since map produces lazy sequence expect future not started, until call deref on it. deref expected block until future returns result. map elements sequentially, expected code run 9 sec, runs in 5.

could explain why?

clojure lazy-seqs make no promise maximally lazy.

+user=> (take 1 (for [i (range 1000)] (doto (println " - printed")))) (0  - printed 1  - printed 2  - printed 3  - printed 4  - printed 5  - printed 6  - printed 7  - printed 8  - printed 9  - printed 10  - printed 11  - printed 12  - printed 13  - printed 14  - printed 15  - printed 16  - printed 17  - printed 18  - printed 19  - printed 20  - printed 21  - printed 22  - printed 23  - printed 24  - printed 25  - printed 26  - printed 27  - printed 28  - printed 29  - printed 30  - printed 31  - printed 0) 

when seq called on vector (most lazy operations implicitly call seq on collection argument), produces chunked data type, realizes batches of results @ time, instead of 1 one. if need control consumption of data, can forces unchunking.

+user=>  (defn unchunk [s]   (when (seq s)     (lazy-seq       (cons (first s)             (unchunk (rest s)))))) #'user/unchunk +user=> (take 1 (for [i (unchunk (range 1000))] (doto (println " - printed")))) (0  - printed 0) 

of course, simpler option in case use type isn't chunked

+user=> (take 1 (for [i (take 1000 (iterate inc 0))] (doto (println " - printed")))) (0  - printed 0) 

Comments

Popular posts from this blog

sequelize.js - Sequelize group by with association includes id -

android - Robolectric "INTERNET permission is required" -

java - Android raising EPERM (Operation not permitted) when attempting to send UDP packet after network connection -