Reputation: 131
I start to read/work on clojure and for that I start to read in parallel 'Programming Clojure' and 'Practical Clojure' books. I saw there one example of how lazy sequence working and for me was very clear in order to understand how lazy-seq work but unfortunately it doesn't work or at least not how I expect.
here is the example:
(defn square[x]
(do
(println "[current.elem=" x "]")
(* x x))
)
(def var-00 (map square '(1 2 3 5 6 4)))
when I call:
var-00
, I expect that no message to print on console(REPL) but I got the follow result:
([current.elem= 1 ][current.elem= 2 ]1 [current.elem= 3 ]4 [current.elem= 5 ]9 [current.elem= 6 ]25 [current.elem= 4 ]36 16)
this mean that the function map was called even I expect to nothing happen since 'var-00' is just a reference to function 'map'; and more awkward from my point of view, if I call:
(nth var-00 2)
I got:
[current.elem= 1 ][current.elem= 2 ][current.elem= 3 ]9
, and if I call again:
(nth var-00 3)
I got:
[current.elem= 1 ][current.elem= 2 ][current.elem= 3 ][current.elem= 5 ]25;
previous elements(1,2,3) was computed again I my opinion those elements should be 'cached' by first call and now only element 5 should be computed. Did I do something wrong or I didn't fully understand how lazy sequence working in clojure ? As a mention I use IntellijIDEA and LaClojure plugin to run the program.
Thanks Sorin.
Upvotes: 1
Views: 229
Reputation: 51450
Just checked your coed in Clojure REPL, it works fine for me. Every element got printed only once (when it's evaluated the first time).
I even tried your example in Clojure online REPL:
But there is one thing that you got wrong. REPL executes each command and then prints its results, so when you type var-00
REPL resolves the symbol and then, in order to print it, executes the whole lazy sequence:
It have nothing to do with lazy sequences, it's just how REPL works:
Upvotes: 2
Reputation: 353
Lazy Evaluation dosen't mean that things will be cached. It means that inside a calculation an element will only be evaluated, if it is needed for the result. If an element is needed twice for the result, it might be evalueated twice.
If you want to have automatic caching of elements there is the memoize
function, which will return a transformed version of the input function with added caching of results. This is also a easy way to implement dynamic programming
Upvotes: -3