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