On Sunday, April 14, 2013 2:58:55 AM UTC+2, tyaakow wrote:

> I'm reading Clojure Programming book by O'Reilly..
>
> I came over an example of head retention. First example retains reference 
> to d (I presume), so it doesnt get garbage collected:
>
> (let [[t d] (split-with #(< % 12) (range 1e8))]
>     [(count d) (count t)]);= #<OutOfMemoryError java.lang.OutOfMemoryError: 
> Java heap space>
>
>
*split-with* gives you two windows into the same original sequence, which 
is *(range 1e8)*. You are first realizing the tail part *d*, then the head 
part *t*. So you are retaining the head while realizing most of the 
sequence.
 

> While second example doesnt retain it, so it goes with no problem:
>
> (let [[t d] (split-with #(< % 12) (range 1e8))]
>     [(count t) (count d)]);= [12 99999988]
>
>
Here the computation happens in the opposite order and you do not retain 
the head while realizing *d*.
 

> If I try to return just [(count d)], like this:
>
> (let [[t d] (split-with #(< % 12) (range 1e8))]
>     [(count d)])
>
> - it seems to create same memory problem. Why is that?
>
This happens because *t* is bound to the head of the sequence, even if you 
are not using it. This is probably a bug because the compiler should 
realize that *t* is not used and not bind it at all, or at least unbind it 
before evaluating *(count d)*.
 

> Further, I recall reading that count in every case realizes/evaluates a 
> sequence. So, i need that clarified.
>
As *count* realizes one element after another, it doesn't on its own retain 
a reference to the past elements. However, if you have another reference to 
the head of the sequence, then you'll transitively hold a reference to each 
and every member of the sequence, causing the complete sequence to stay in 
memory at the same time. This is what the "lose your head" maxim is about.

-marko
 

-- 
-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to