Yes, you’re right that neither directly handles `concat`, however CLJ-1583 improves the behaviour of both your examples and is _necessary_ to fix any `apply` related laziness issues
user=> (first (apply concat (map #(do (println %) [%]) (list 1 2 3 4 5)))) 1 2 3 1 user=> (first (mapcat #(do (println %) [%]) (list 1 2 3 4 5))) 1 2 3 1 While CLJ-1218 in conjunction with CLJ-1583 “fixes” the mapcat example: user=> (first (mapcat #(do (println %) [%]) (list 1 2 3 4 5))) 1 1 So to make all your examples as lazy as possible we need a combination of CLJ-1218, CLJ-1583 and a `join`-like `concat` > On 18 Jul 2018, at 09:24, Mark Engelberg <mark.engelb...@gmail.com> wrote: > > Thanks, I hadn't seen those issues. > https://dev.clojure.org/jira/browse/CLJ-1218 > <https://dev.clojure.org/jira/browse/CLJ-1218> talks about mapcat, and > https://dev.clojure.org/jira/browse/CLJ-1583 > <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 > <mailto: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-1583> > https://dev.clojure.org/jira/browse/CLJ-1218 > <https://dev.clojure.org/jira/browse/CLJ-1218> > > On Wed, 18 Jul 2018, 08:28 Mark Engelberg, <mark.engelb...@gmail.com > <mailto: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 > <mailto: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 > <mailto:clojure%2bunsubscr...@googlegroups.com> > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > <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 > <mailto:clojure+unsubscr...@googlegroups.com>. > For more options, visit https://groups.google.com/d/optout > <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 > <mailto: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 > <mailto:clojure%2bunsubscr...@googlegroups.com> > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > <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 > <mailto:clojure+unsubscr...@googlegroups.com>. > For more options, visit https://groups.google.com/d/optout > <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 > <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 > <mailto:clojure+unsubscr...@googlegroups.com>. > For more options, visit https://groups.google.com/d/optout > <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.