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