On Fri, Dec 31, 2010 at 12:25 AM, ehanneken <ehanne...@pobox.com> wrote:
> I spent a long time debugging some Clojure code yesterday.  The
> essence of it looked similar to this:
>
> (defn items []
>  (mapcat expensive-function (range 0 4000 100)))
>
> . . . (take 5 (items)) . . .
>
> expensive-function is a function that issues an HTTP GET to retrieve a
> vector of data.  Since range's docstring says it returns a lazy
> sequence, and since mapcat is defined in terms of map and concat,
> which are both supposed to return lazy sequences, I expected (take 5
> (items)) to cause only one HTTP GET.  In reality, it causes 32 GETs.
> That's kind of costly in time and space, considering I merely wanted
> the first 5 of the 100 items returned in the response to the first
> GET.
>
> This behavior was baffling to me at first, but after some research I
> found section 12.3 of _The Joy of Clojure_, which mentions that ever
> since Clojure 1.1 some functions (such as range) which are advertised
> as lazy are actually moderately eager, realizing chunks of up to 32
> elements at a time.

Interesting. I find it odd, though, that that would result in
expensive-function being called 32 times. I'd expect mapcat to cause
it to be called once; so you'd realize the first 32 elements of (range
0 4000 100) and consume one, and realize the first 100 elements of
(mapcat expensive-function (range 0 4000 100)) and consume five.

Is mapcat also semi-eager, then?

-- 
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