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.