It seems like the behavior has changed a little in Clojure 1.3, but still warrants some additional discussion. Here's what I saw
(count (range 100000000)) user=> 100000000 (apply count [(range 100000000)]) user=> 100000000 (apply + (range 100000000)) user=> 4999999950000000 (. count (applyTo (seq [(range 100000000)]))) user=> OutOfMemoryError GC overhead limit exceeded clojure.core/range (core.clj:2599) (clojure.lang.AFn/applyToHelper count (seq [(range 100000000)])) user=> 100000000 (clojure.lang.RT/boundedLength (seq [(range 100000000)]) 20) user=> 1 (let [x (range 100000000)] (clojure.lang.RT/boundedLength (seq [x]) 20) (count x)) user=> 100000000 (count (clojure.lang.Util/ret1 (.first (seq [(range 100000000)])) nil)) user=> 100000000 (.invoke count (clojure.lang.Util/ret1 (.first (seq [(range 100000000)])) nil)) user=> OutOfMemoryError GC overhead limit exceeded clojure.lang.ChunkedCons.next (ChunkedCons.java:42) (.invoke count (range 100000000)) user=> OutOfMemoryError GC overhead limit exceeded clojure.core/chunk- cons (core.clj:646) (let [c #^clojure.lang.AFunction count] (.invoke c (clojure.lang.Util/ret1 (.first (seq [(range 100000000)])) nil))) user=> 100000000 This leads me to believe that there may be a bug here, but I am going to take a closer look. If that is the case I will file an issue in JIRA. Cheers, Aaron Bedra -- Clojure/core http://clojure.com On May 18, 11:50 pm, Ken Wesson <kwess...@gmail.com> wrote: > In Clojure 1.2.0: > > => (count (range 100000000)) > 100000000 > => (applycount [(range 100000000)]) > #<CompilerException java.lang.OutOfMemoryError: GC overhead limit > exceeded (NO_SOURCE_FILE:0)> > > I'm not sure why this is happening, but it seemsapplyis causing theheadof the > range to be held somewhere. > > This: > > => (apply+ (range 100000000)) > 4999999950000000 > > indicates that it does not do so if the enormous seq is applied to a > rest argument of the fn; with count, it should just be passing the > (unrealized!) seq as a parameter to count. But apparently it's > internally hangingontoa reference to that seq. > > Tracking it down: > > => (. count (applyTo (seq [(range 100000000)]))) > #<Boom!> > > => (clojure.lang.AFn/applyToHelper count (seq [(range 100000000)])) > #<All your base are belong to us!> > > => (clojure.lang.RT/boundedLength (seq [(range 100000000)]) 20) > 1 ; No kablooey there > > => (let [x (range 100000000)] (clojure.lang.RT/boundedLength (seq [x]) > 20) (count x)) > 100000000 ; And again no kaboom; boundedLength isn't causing this > > => (count (clojure.lang.Util/ret1 (.first (seq [(range 100000000)])) nil)) > 100000000 ; Looks like ret1 isn't the cause either. > > => (.invoke count (clojure.lang.Util/ret1 (.first (seq [(range > 100000000)])) nil)) > #<You are on the way to destruction!> > > ; Er, aren't those last two supposed to be *synonymous*?! > > ; And finally > > => (.invoke count (range 100000000)) > #<You have no chance to survive make your time!> > > ; Now here is something really weird: > > => (let [c #^clojure.lang.AFunction count] (.invoke c (range 100000000))) > 100000000 > > ; No kaboom! > > As near as I can tell, I've found 2 separate buggy behaviors here. > > 1: If an interop call uses reflection and passes a lazy seq, theheadgets > heldontosomewhere. > > 2: A non-reflection-using (.invoke count (range 100000000)) does not blow > up in the REPL, but invoke(count, huge_seq); does when > applyToHelper calls it. > > => (let [c #^clojure.lang.AFunction count] (.invoke c > (clojure.lang.Util/ret1 (.first (seq [(range 100000000)])) nil))) > 100000000 > > Nope, still not ret1 (which is in fact supposed to prevent this sort of > thing). > > And theapplyfunction hints the function argument as IFn so it isn't > caused by reflection inapply. > > What the devil is going on here??? > > -- > Protege: What is this seething mass of parentheses?! > Master: Your father's Lisp REPL. This is the language of a true > hacker. Not as clumsy or random as C++; a language for a more > civilized age. -- 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