Will lazy seq last to evaluate all elements in clojure?

Suppose we have an expensive computation of expensive . If we believe that map creates lazy seq, then does the following function perform expensive for all elements of the displayed collection or only for the last?

 (last (map expensive '(1 2 3 4 5))) 

those. Does this value expensive for all values ​​1..5 or only (expensive 5) ?

+4
source share
3 answers

The entire collection will be appreciated. A simple test answers your question.

 => (defn exp [x] (println "ran") x) => (last (map exp '(1 2 3 4 5))) ran ran ran ran ran 5 
+7
source

There is no random access for lazy sequences in Clojure.

In a sense, you can consider them equivalent to singly linked lists β€” you always have the current element and function to get the next.

That way, even if you just call (last some-seq) , it will evaluate all the elements of the sequence, even if the sequence is lazy. If the sequence is finite and small enough (and if you do not hold the head of the sequence in the link) it is good when it comes to memory. As you noted, there is a problem with the runtime that can occur if the function used to get the next element is expensive.

In this case, you can compromise to use a cheap function to go all the way to the last element:

(last some-seq)

and then apply the function only to this result:

(expensive (last some-seq))

+2
source

last will always force you to evaluate the lazy sequence - this is clearly necessary, because you need to find the end of the sequence and, therefore, you need to evaluate the lazy seq at each position.

If you want laziness in all the individual elements, one way is to create a sequence of lazy sequences as follows:

 (defn expensive [n] (do (println "Called expensive function on " n) (* nn))) (def lzy (map #(lazy-seq [(expensive %)]) '(1 2 3 4 5))) (last lzy) => Called expensive function on 5 => (25) 

Please note that the latter in this case still forces us to evaluate the lazy top-level sequence, but does not force us to evaluate the lazy sequences contained in it, except for the last one we pull out (because it is printed using REPL).

+2
source

Source: https://habr.com/ru/post/1383214/


All Articles