Not only did my question get answered, but I learned several new things in the process.
Thanks! Dave On Wed, Oct 20, 2010 at 1:52 PM, Alan <a...@malloys.org> wrote: > When you work with a lazy sequence, Clojure (java really) > automatically garbage-collects elements you're done with. It can only > be certain you're done with them if you no longer have any reference > to them, direct or indirect. If you've bound the head of the sequence > to a local, then you can still access every element of the lazy > sequence, so none can be garbage collected. If instead you pass the > element through a set of operations without ever binding it to > anything, each element can be GCed immediately after you're done > processing it (though in practice they won't be until space is > needed). > > Observe the difference: > > user=> (nth (map #(make-array Double/TYPE (* % 10000)) > (range)) > 100) > #<double[] [...@781046> > > user=> (let [x (map #(make-array Double/TYPE (* % 10000)) > (range))] > (nth x 100)) > java.lang.OutOfMemoryError: Java heap space (NO_SOURCE_FILE:0) > > > You will probably need different numbers to reproduce these results on > your system depending on how much heap space you let clojure have, but > that's the idea. > > And you make a good point about binding sequences to locals in a let. > I'm not sure, but I think you're right: if the sequences are large > enough the let-version will fail while the ->> (or nested-forms) > version will succeed. > > On Oct 20, 10:34 am, cej38 <junkerme...@gmail.com> wrote: >> This question leads into something that I read in Joy of Clojure (page >> 161 in the latest MEAP edition): >> "If you manage to hold onto the head of a sequence somewhere within a >> function, then that sequence will be prevented from being garbage >> collected. The simplest way to retain the head of sequence is to bind >> it to a local. This condition can occur with any type of value bind be >> it to a reference type or through the usage of let or binding." >> >> I am not sure what this means, but I think it would mean that using >> let as you do, could cause garbage collection problems. Thus, it >> might be better to follow the advice of Stuart and Luc. >> >> Chad >> >> PS. Clarification of the statement from the Joy of Clojure would be >> helpful. >> >> On Oct 19, 11:19 pm, Dave Ray <dave...@gmail.com> wrote: >> >> > Hey, >> >> > I'm parsing a file with a chain of filter and map operations. To make >> > it a little more readable (to me), I put the steps in a let like this: >> >> > (defn parse-dictionary >> > [reader] >> > (let [lines (read-lines reader) >> > trimmed (map #(.trim %1) lines) >> > filtered (filter is-dictionary-entry? trimmed)] >> > (map parse-entry filtered))) >> >> > Is this style of let considered good/bad stylistically? Are there >> > technical tradeoffs between this and a bunch of nested forms? >> >> > Thanks! >> >> > Dave >> >> > > -- > 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 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