On Wed, Nov 25, 2009 at 12:10:36AM -0800, Gabi wrote:

>How come that infinite recursions under lazy-seq won't crash the
>program, whilst regular infinite recursion would crash the program ?
>What's the trick ?
>
>For example why doesn't the following "repeatedly" never crash?
>
>(defn repeatedly
>  [f] (lazy-seq (cons (f) (repeatedly f))))
>
>(last (repeatedly rand)) ;won't crash

The JVM doesn't support tail call elimination, so an infinite
retursion causes a new stack frame for each call.  The stack is fairly
small and will quickly be exhausted.

The lazy-seq, instead, wraps the contents up into a function closure
and wraps it in a clojure.lang.LazySeq.  This causes a few heap
allocations.  If you were to keep the head of this chain, you would
also exhaust the heap (which would take a while longer).  But since
your example is only walking along next, each item generated contains
no more references, and can be garbage collected.

Lazy-seq basically turns a stack allocation into a heap allocation.
This both allows for not allow of the sequence to be allocated, but
allows the earlier parts of the sequence to be collected.

Try:

  (let [r (repeatedly rand)]
    (last r)
    r)

which will try to keep the whole sequence in memory, and eventually
exhaust your heap.

David

-- 
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