On Thu, Apr 10, 2025 at 1:49 AM Milles, Eric (TR Technology) via dev
<dev@groovy.apache.org> wrote:
>
> My general concern is the number of overloads and variants.

Yes, maybe we break compatibility for Groovy 5 and just keep the
current names. That would keep name overloads/maintenance down. I
think with gatherers becoming more familiar and virtual threads,
having lazy options will become more commonplace. If we ever wanted to
refresh Gpars with virtual threads, having a clean slate would be a
good thing.

> collect, collectMany and findAll would probably be named something else if 
> created anew today.  Adding to this creates confusion IMO.  Do you have a 
> Java stream and Groovy as-is version to compare against for each proposed new 
> method?  It helps me at least to see what it would take to do the same 
> without the extension.

You probably need a library like Gatherers4j in combination with
normal streams to cover off all the methods. That was in fact what
kick-started the journey I have been on for the last few weeks. I have
a blog post which does just that. I stopped working on it when these
issues came up. I'll revamp and send in its current raw form, though
it's not quite ready for publication.

Paul.

> ________________________________
> From: Jochen Theodorou <blackd...@gmx.org>
> Sent: Wednesday, April 9, 2025 6:21 AM
> To: dev@groovy.apache.org <dev@groovy.apache.org>
> Subject: [EXT] Re: [DISCUSS] Lazy findAll, collect, collectMany
>
> External Email: Use caution with links and attachments.
>
> On 09.04.25 03:25, Paul King wrote:
> > Hi folks,
> >
> > [I sent this to grails dev list but meant to send it here and CC them
> > for feedback - anyway, it is here now, apologies if you see this
> > twice.]
> >
> > I have been looking at the functionality in Groovy-stream[1] and
> > Gatherers4J[2] lately with a view to filling any gaps in Groovy's
> > iterator DGM methods. I'm not trying to replicate everything they
> > contain, just looking for the most useful functionality Groovy might
> > be missing.
> >
> > The biggest missing pieces at this point in my mind are lazy (Iterator
> > return value) variants of findAll, collect, and collectMany. Groovy's
> > current variants are eager (return collections and lists).
> > Groovy-stream gets around this by adding stream-named variants:
> > filter, map, and flatMap.
>
>
> does Iterator really automatically mean lazy? Is this possible then?
>
> def l = [1,2,3]
> def iterator = l.iterator().findAll{it>1}
> l[0] = 20
> assert iterator.toList() == [20,2,3]
>
> The combination of lazy and mutable can be problematic. Also, can I do
> iterator.toList() multiple times?
>
> > One option is to break backwards compatibility (Groovy 5 only). So
> > only for the versions of those methods which take an Iterator as
> > input, change the return type to be Iterator. Given how widely used
> > those methods are, I don't think that is an option for us.
>
> well... we could have lazyIt() which return a LazyIterator. that would
> make things clear.
>
> > Actually, findAll currently doesn't have an Iterator variant, so we
> > could add that but it would still be a behavioral compatibility
> > breakage since the Object version is used for Iterators and it returns
> > a list.
> >
> > So, we could give up on lazy variants for those methods, but again
> > given how commonly used they are, that is a pretty big gap.
> >
> > So, the other option is to provide alternative names. The best to me seem:
> >
> > (A) findAllLazy, collectLazy, collectManyLazy
> > (B) findAllThen, collectThen, collectManyThen
> > (C) filter, map, flatMap
> > (D) something else?
>
> (E) lazyIt()
>
> I am pretty sure it will not be considered as because it is a bit
> ugly... but frankly I am no fan of A at all for the very same reason. B
> I find more nice because it is more semantics based.
>
> hmm... what happens if you mix lazy and non-lazy... like for example
> findAllthen(...).findAll(...)
>
> > Option (C) is what Groovy-stream did and would be familiar to Java
> > Stream users but folks are going to ask, why can't I have that "alias"
> > for Iterables and arrays, but the intent here is just for the Iterator
> > variants. I think Lazy best conveys that. Use without "Lazy" for the
> > eager (think terminal operator) variant and with "Lazy" for the lazy
> > (think intermediate operator) variant. It also is easier to extend,
> > the fourth method in terms of gaps is collectEntries, which currently
> > returns a Map. An Iterator<Map.Entry> return value could be made for
> > collectEntriesLazy if we wanted.
>
> somehow does not really convince me all.
>
> > Note that many of our operators are terminal in nature, find, count*,
> > inject, etc, so this isn't about doing this for all operators
> > eventually.
>
> but findAllThen does not come over as terminal. If they are supposed to,
> then I don't find the names fitting in the cases of A and B.
>
> bye jochen
>

Reply via email to