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.