Sunday, 31 July 2011

Lazy Sequences

I like this a lot:
;; define a function with a side effect to show when it is called
(defn square [x]
  (do
    (println (str "Processing: " x))
    (* x x)))

;; define map-result which is result of calling square for every item in the list
(def map-result (map square '( 1 2 3 4 5 6 7 8)))
First time, enough of the lazy sequence is evaluated to generate the result:
practical-clojure.chpt5> (nth map-result 2)
Processing: 1
Processing: 2
Processing: 3
9
The next time, with the same args, the previous calculation was cached, so nothing to evaluate:
practical-clojure.chpt5> (nth map-result 2)
9
The next call it needs to evaluate a couple more of the lazy sequence:
practical-clojure.chpt5> (nth map-result 4)
Processing: 4
Processing: 5
25
And again, this is cached:
practical-clojure.chpt5> (nth map-result 4)
25
This is possible because a sequence looks like:
first --> (rest)
first --> (first --> (rest))
first --> (first --> (first --> rest))
Rest is only evaluated when it is required.

No comments:

Post a Comment