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

Reply via email to