(doall coll) (doall n coll)
When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. doall can be used to force any effects. Walks through the successive nexts of the seq, retains the head and returns it, thus causing the entire seq to reside in memory at one time.
;; Nothing is printed because map returns a lazy-seq
user=> (def foo (map println [1 2 3]))
#'user/foo
;; doall forces the seq to be realized
user=> (def foo (doall (map println [1 2 3])))
1
2
3
#'user/foo
;; where
(doall (map println [1 2 3]))
1
2
3
(nil nil nil)
;;map a function which makes database calls to either retrieve or
;;create and retrieves records from the database over a vector of values.
;;The function returns a map of fields and values
user=> (map #(db/make-n-get-or-get :person {:name %}) ["Fred" "Ethel" "Lucy" "Ricardo"])
JdbcSQLException The object is already closed [90007-170] org.h2.message.DbE
xception.getJdbcSQLException (DbException.java:329)
;;database connection was closed before we got a chance to do our transactions
;;lets wrap it in doall
user=> (doall (map #(db/make-n-get-or-get :person {:name %})
["Fred" "Ethel" "Lucy" "Ricardo"]))
DEBUG :db insert into person values name = 'Fred'
DEBUG :db insert into person values name = 'Ethel'
DEBUG :db insert into person values name = 'Lucy'
DEBUG :db insert into person values name = 'Ricardo'
({:name "Fred"} {:name "Ethel"} {:name "Lucy"} {:name "Ricardo"})
;;notice that unlike using dorun, this returns a list of maps
;; The (doall n coll) form only forces the first n (or more) items in coll to
;; be realized, but still returns the entire coll.
(def pr-123 (lazy-seq (cons (pr 1)
(lazy-seq (cons (pr 2)
(lazy-seq (cons (pr 3) nil)))))))
#'user/pr-123
;; Since doall returns the collection, be careful not to let the REPL realize
;; the whole thing, as it would if we were to call (doall 1 pr-123) instead.
user=> (do (doall 1 pr-123) (println))
12
nil
;; The 1 is triggered when (seq pr-123) is called, then the 2 is triggered
;; when (next pr-123) is called (both inside dorun, via doall).
user=> pr-123
3(nil nil nil)
;; The 3 is finally triggered when the REPL realizes the entirety of pr-123
;; pr-123 is built of nested lazy-seq's because (map pr coll) isn't very lazy:
(do (doall 1 (map pr (range 100))) (println))
012345678910111213141516171819202122232425262728293031
nil
;; Due to occult clojure.lang.RT/JVM internals (?), (next coll) on this sort
;; of coll realizes the items in batches of 32 each.
;; #'for is create lazy-seq
(def x (for [i (range 10)]
i)
(type x) ;;=> clojure.lang.LazySeq
;; doall return evaluated value
(doall x) ;;=> (0 1 2 3 4 ...)
;; Notice!
;; but it is clojure.lang.LazySeq
(type (doall x)) ;;=> clojure.lang.LazySeq
;; if you want to get list ...
(into-array x)
(type (into-array x)) ;;=> [Ljava.lang.Long;