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.

Reply via email to