Great Q&A on this, thanks Marko!

On Sunday, 14 April 2013 19:13:51 UTC+1, Marko Topolnik wrote:
>
> 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