Hi,
On 25 Nov., 05:06, Sunil S Nandihalli <[email protected]>
wrote:
> (defn every-nth [n coll]
> (letfn [(evn [cn s]
> (when s
> (if (= cn 1)
> (lazy-seq (cons (first s) (evn n (next s))))
> (evn (dec cn) (next s)))))]
> (evn n coll)))
Since you want to learn how lazy-seq works here some feedback.
* Make the lazy-seq the outer-most part of your function
to allow as much laziness as possible. There other
opinions out there about the placement of lazy-seq, but
there are also a lot of people complaining about eg. a
filter doing an expensive predicate call because the
input sequence is not as lazy as it could be. By placing
lazy-seq outermost you leave the decision to them when
to realize an element.
* You should call seq on coll before passing it to evn.
Think of [] as input. It will be truthy in the when check
and we do some unnecessary loop, where we actually could
short circuit.
* Don't call next in the true branch of the if. It realises
an element of the input sequence where it is not
necessary. Use rest.
* Don't call evn in the false branch of the if. It will be
true recursion and might blow the stack for large n. You
Use recur.
Here is the version I would write in this case.
(defn every-nth
[n coll]
(let [step (fn step [s]
(lazy-seq
(loop [s (seq s)
cnt n]
(when s
(if (= cnt 1)
(cons (first s) (step (rest s)))
(recur (next s) (dec cnt)))))))]
(step coll)))
* lazy-seq is outer-most.
* The recur is turned into a loop to avoid stacking lazy-seq
on lazy-seq.
* The input sequence is only realised inside the lazy-seq.
Also in the true branch we use rest to defer realisation
of the next seq step. In the false branch we use next,
because we need the value anyway.
As a rule of thumb: write your generating function with
"normal" recursion first. Then simply wrap a lazy-seq
around it.
Hope that helps.
Sincerely
Meikel
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en