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

Reply via email to