Lazy consistency is where we evaluate consistency as and when necessary. (hence lazy). Once the result is evaluated, it is cached so that it can be reused (and we donβt need to do the work again). If you try to implement an element of a sequence that has not yet been evaluated, clojure evaluates it and returns a value for you. However, he also does some extra work. It suggests that you can evaluate the next element in a sequence and do it for you too. This is to avoid some performance overheads whose exact nature is above my skill level. Thus, when you say (first lz-seq), it actually computes the first, as well as the next few elements in seq. Since your println request is a side effect, you can see how the evaluation happens. Now, if you say (second lz-seq), you will no longer see println, since the result has already been evaluated and cached.
The best way to see your sequence is lazy:
user=> def lz-seq (map #(do (println "fn call!") (identity %)) (range 400))
This will print a few calls to "fn!". but not all 400 of them. This is because the first call will actually complete the evaluation of more than one element of the sequence.
I hope this explanation is clear enough.
source share