In Clojure 1.2.0: => (count (range 100000000)) 100000000 => (apply count [(range 100000000)]) #<CompilerException java.lang.OutOfMemoryError: GC overhead limit exceeded (NO_SOURCE_FILE:0)>
I'm not sure why this is happening, but it seems apply is causing the head of 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 hanging onto a 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, the head gets held onto somewhere. 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 the apply function hints the function argument as IFn so it isn't caused by reflection in apply. 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