Hi,

On Fri, Nov 19, 2010 at 11:44 AM, babui <jmgim...@gmail.com> wrote:

> I've been playing with lazy sequences defined by autoreferential
> definition. For instance:
>
> (def ones (lazy-seq (cons 1 ones)))
>
> which is equivalent to (def ones (repeat 1)).
>
> My problem arises when defining the sequence of fibonacci numbers.
> With this definition:
>
> (def fibs
>  (lazy-seq (list* 0 1 (map + fibs (drop 1 fibs)))))
>
> all works, for instance:
>
> user=> (take 10 fibs)
> (0 1 1 2 3 5 8 13 21 34)
>
> But if I change (drop 1 fibs) with (rest fibs), that is:
>
> (def fibs
>  (lazy-seq (list* 0 1 (map + fibs (rest fibs)))))
>
> and try to get the first 10, I get:
>
> user=> (take 10 fibs)
> java.lang.StackOverflowError
>
> My problem is that I don't understand why.
>

(drop 1 fibs) is fully lazy, it doesn't look at fibs to return a new seq
(rest fibs) needs to evaluate the 1st item to return
(next fibs) needs to evaluate the 1sy item and the rest (so most of the time
it means evaluating the 2nd item too)



(def fibs
 (lazy-seq (list* 0 1 (map + fibs (rest fibs)))))

when you try to get the first item of the seq, it forces eval of (list* 0 1
(map + fibs (rest fibs)))
list* being a fn, 0, 1 and (map + fibs (rest fibs)) are evaluated
map being a fn, +, fibs and (rest fibs) are evaluated
and as as I mentioned above rest forces evaluation of the lazy-seq body (the
list* call) which is exactly what we are actually doing, so we call
ourselves until the stack blow.

(rest 1 fibs) on the other hand delay the evaluation and saves us from the
stack overflow.

hth,

Christophe

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to