Hi folks,

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.

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.

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?

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.

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.

Thoughts?

Paul.


[1] https://github.com/timyates/groovy-stream
[2] https://github.com/tginsberg/gatherers4j

Reply via email to