Here are two alternatives that should work right now: UnaryOperator<Integer> multiplier(int multiplicand) { return x -> x * multiplicand; }
List<Integer> list = [1, 2, 3] list.collect(multiplier(2)) // fails list.collect(multiplier(2).&apply) list.collect(this.&miltiplier.curry(2)) -----Original Message----- From: Milles, Eric (TR Technology) <eric.mil...@thomsonreuters.com> Sent: Wednesday, April 28, 2021 12:07 PM To: dev@groovy.apache.org Subject: RE: GDK retrofit for Java functional interfaces It is best IMO to open a JIRA ticket first so that discussion and metadata can be tracked. Beyond that, opening a pull request on github with a link back to the ticket should suffice. The ticket prevents surprise when a pull request shows up. And I'd suggest starting with a small change first. -----Original Message----- From: Christopher Smith <chry...@gmail.com> Sent: Wednesday, April 28, 2021 11:36 AM To: dev@groovy.apache.org Subject: Re: GDK retrofit for Java functional interfaces My case for `with` and `tap` is that in both cases they're immensely useful as general pipeline operations, and being able* to use `with(Foo::transform)` but not `with(Foo.transform(param))` is inconsistent and has been an in-real-use frustration for my current project. Where the Closure is explicitly manipulated it certainly makes sense to keep that overload first-class. What's the Apache process for doing this? I know how to open a ticket (heh), but can I just open a GitHub PR against apache/groovy? Looks like putting GROOVY-ABCD in the commit summary will auto-link it. On Wed, Apr 28, 2021 at 11:19 AM Milles, Eric (TR Technology) <eric.mil...@thomsonreuters.com> wrote: > > For any DGM that accepts Closure but does not use closure delegation or > multiple closure param signatures, we could mark the Closure version > deprecated and add an @FunctionalInterface equivalent. Existing code that > uses closure literals or method pointers should be okay. There may be one or > two edge cases out there. > > > > For the ones that use delegation like "with" and "tap" I don't think there is > a strong case for making a change. > > > > I think it would probably be best to submit one JIRA ticket for each group of > methods. That is, one for "collect", one for "findAll", etc. So we can > break the problem down and test things a little at a time. > > > > From: Christopher Smith <chry...@gmail.com> > Sent: Wednesday, April 28, 2021 11:02 AM > To: dev@groovy.apache.org > Subject: Re: GDK retrofit for Java functional interfaces > > > > The "side by side" approach is my second option; the only significant > downside is an increase in the surface area of the extension landscape. I > think Jochen excellently described the distinction of some cases (`with`) > where Closure awareness is still needed for reasons of delegate manipulation, > and in these cases adding a Function signature (essentially a "map" > operation) would make more sense. > > > > To be frank, I can't see a good reason for saying that `collect` (e.g.) > should just be given up in preference to an explicit stream. In such a case, > there is no disadvantage whatsoever that I can see to trimming the GDK > signature back to the more vanilla functional interface and interpreting a > Closure as that interface when desired, as is already done for interop > everywhere else. > > > > On Wed, Apr 28, 2021, 09:22 Milles, Eric (TR Technology) > <eric.mil...@thomsonreuters.com> wrote: > > Is there any reason that these cannot exist side-by-side as extension > methods? If they are safe to co-exist, then you can create each of the > alternatives in turn within a sample project and try them out. The extension > method mechanism is open and available. > > public static <S,T> List<T> collect(Iterable<S> self, > @ClosureParams(FirstParam.FirstGenericType.class) Closure<T> > transform) > > public static <S,T> List<T> collect(Iterable<S> self, > Function<? super S, ? extends T> transform) > > > > Otherwise, I think the going advice is to use Java streams if you want > a lambda/method reference friendly API. There is an ticket in JIRA > about making streams a bit more "groovy": > https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fissu > es.apache.org%2Fjira%2Fbrowse%2FGROOVY-10026&data=04%7C01%7Ceric.m > illes%40thomsonreuters.com%7Cd2fd247908f84786338b08d90a63bc3c%7C62ccb8 > 646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637552245742549051%7CUnknown%7CTW > FpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6 > Mn0%3D%7C1000&sdata=TTaemEkQLuQ7uTXXMdA%2Fjgx2%2BJMxMg%2BnpBgqImKL > fCI%3D&reserved=0 > > > -----Original Message----- > From: Christopher Smith <chrylis+gro...@gmail.com> > Sent: Tuesday, April 27, 2021 6:37 PM > To: dev@groovy.apache.org > Subject: GDK retrofit for Java functional interfaces > > Since Paul is now threatening us with a 4.0 beta, I wanted to float an idea > that I've been thinking over for a bit now that might be best to add there > (though maybe it would be okay in 3 still, with the Java 8 baseline). > > A large number of the GDK extension methods (particularly stuff like > `with`, `collect`, and similar) have signatures that rely explicitly > on Closure for their strategies. This means that there are > interoperability problems with libraries that provide strategy > implementations as functional types; e.g., imagine this trivial > example: > > ``` > public UnaryOperator<Integer> multiplier(int multiplicand) { > return x -> x * multiplicand; > } > ``` > > I can't say `[1, 2, 3].collect(multiplier(2))`, because `collect` takes only > a Closure. > > I would like to (ideally) alter the signatures of the methods in > DefaultGroovyMethods and similar to replace Closure with the "more static" > interfaces where possible; most of these cases would end up being Function, > Consumer, and some of the other usual suspects, with some of the extension > methods being duplicated to account for the cases where the GDK currently > does runtime magic like arity detection. > In the alternative, at least adding overrides for these would support > language-level interoperability. > > What is the opinion regarding making this change, and what kinds of > compatibility problems might result from replacing Closure with (e.g.) > Function rather than adding a new override? -- Christopher Smith