Clojure - using a loop and repeating with a lazy sequence

If I return lazy-seq from a function like this:

(letfn [(permutations [s] (lazy-seq (if (seq (rest s)) (apply concat (for [xs] (map #(cons x %) (permutations (remove #{x} s))))) [s])))]) 

If I use a recur loop as shown below, would the list be looked forward to?

 (loop [perms (permutations chain)] (if (empty? perms) (prn "finised") (recur (rest perms)))) 

If it is impatiently appreciated, can I use loop..recur for a lazy loop over what is returned from the permutations function?

+5
source share
1 answer

The list is lazily evaluated by recur loop code.

You can try it yourself. Let make permutations print something every time it returns a value by adding a call to println .

 (defn permutations [s] (lazy-seq (if (seq (rest s)) (apply concat (for [xs] (map #(cons x %) (permutations (remove #{x} s))))) (do (println "returning a value") [s])))) 

When using loop also print the values ​​when we get to (prn (first perms) .

 (loop [perms (permutations [1 2 3])] (if (empty? perms) (prn "finised") (do (prn (first perms)) (recur (rest perms))))) 

Here is what it prints:

 returning a value (1 2 3) returning a value (1 3 2) returning a value (2 1 3) returning a value (2 3 1) returning a value (3 1 2) returning a value (3 2 1) "finished" 

As you can see, the "return value" and the string of values ​​alternate. Evaluating a lazy seq can be called using doall . If you are fixated on (doall (permutations [1 2 3])) , first it prints all the lines of "return value" and only the value.

+6
source

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


All Articles