Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simplest Lazy function in Clojure

I'm having a tough time understanding laziness.

Can someone help me understand why my function below is not lazy

(defn my-red
    ([f coll] (my-red f (first coll) (rest coll) ))
    ([f init coll] 
      (let [mr (fn [g i c d] 
            (if (empty? c) d 
        (recur  g (g  i (first c)) (rest c)  (conj d (g  i (first c)) ))))] 
    (lazy-seq (mr f init coll [])))))

whereas this example given on clojure.org/lazy is

(defn filter
  "Returns a lazy sequence of the items in coll for which
  (pred item) returns true. pred must be free of side-effects."
  [pred coll]
  (let [step (fn [p c]
                 (when-let [s (seq c)]
                   (if (p (first s))
                     (cons (first s) (filter p (rest s)))
                     (recur p (rest s)))))]
    (lazy-seq (step pred coll))))
like image 725
KobbyPemson Avatar asked Dec 16 '22 03:12

KobbyPemson


2 Answers

The laziness in filter comes from the call to filter in the if branch of the recursive loop. That's where the code hits another lazy-seq and stops evaluating the seq until another element is requested.

Your implementation of my-red hits a call to lazy-seq one and only one time, meaning that your seq is either not evaluated at all or completely evaluated.

like image 105
skuro Avatar answered Jan 30 '23 21:01

skuro


The mr function will just recur through the whole of coll. Perhaps your indentation is misleading you. correctly indented, and with some useless parameters removed the function looks something like this:

(defn my-red
  ([f coll] (my-red f (first coll) (rest coll) ))
  ([f init coll] 
     (let [mr (fn [i c d] 
                (if (empty? c)
                  d 
                  (recur (f i (first c))
                         (rest c)
                         (conj d (f i (first c))))))] 
       (lazy-seq (mr init coll [])))))

Basically, you're wrapping (lazy-seq) around the mr function, which does all the work in one big recur loop.

like image 36
Joost Diepenmaat Avatar answered Jan 30 '23 21:01

Joost Diepenmaat