Thanks, I hadn't seen those issues.
https://dev.clojure.org/jira/browse/CLJ-1218 talks about mapcat, and
https://dev.clojure.org/jira/browse/CLJ-1583 talks about apply. Those are
aspects of the problem, for sure, but fixing those two issues would not
solve the problem with (apply concat ...), I don't think, because another
facet of the problem is that concat's args are of the form [x y & zs].

Gary Fredericks recognizes this problem in the comments for CLJ-1218: "I
realized that concat could actually be made lazier without changing its
semantics, if it had a single [& args] clause that was then implemented
similarly to join above."

But for the most part, the comments are focused on fixing mapcat by
implementing a new function, join, rather than fixing the problem with
concat directly.  Seems better to fix concat, if possible.

I'm truly astonished I haven't gotten bitten by this before.  This is a
pattern I use frequently in my code; I guess I just never had deep enough
recursion for it to slow things down enough for me to realize what was
happening.



On Wed, Jul 18, 2018 at 12:53 AM, Nicola Mometto <brobro...@gmail.com>
wrote:

> This behaviour is known and there are a couple of tickets about it :
>
> https://dev.clojure.org/jira/browse/CLJ-1583
> https://dev.clojure.org/jira/browse/CLJ-1218
>
> On Wed, 18 Jul 2018, 08:28 Mark Engelberg, <mark.engelb...@gmail.com>
> wrote:
>
>> I'm kind of surprised I haven't run across this before, but tonight I was
>> debugging a function that was doing an explosion of computation to return
>> the first value of a lazy sequence, and I was able to reduce the problem
>> down to this example:
>>
>> > (first (apply concat (map #(do (println %) [%]) (list 1 2 3 4 5))))
>> 1
>> 2
>> 3
>> 4
>> 1
>>
>> The last 1 is the return value, but notice that it realized 4 values in
>> order to return the 1.  This has nothing to do with chunked sequences, by
>> the way -- a list is an unchunked sequence.  It appears to be that the way
>> concat is written, it realizes the first two elements, and then another two
>> elements in a recursive call before the lazy-seq kicks in.
>>
>> In the function in question, the "apply concat" was part of a recursion,
>> causing that explosion of realizing values (four at each level of the
>> recursion, it would seem) to get at the first element.
>>
>> Note that this affects mapcat as well, which relies on concat under the
>> hood:
>> > (first (mapcat #(do (println %) [%]) (list 1 2 3 4 5)))
>> 1
>> 2
>> 3
>> 4
>> 1
>>
>> I don't see a quick fix other than writing my own improved
>> concat/mapcat.  Do you?
>>
>> --
>> 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
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
> --
> 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
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to