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<mailto: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://issues.apache.org/jira/browse/GROOVY-10026<https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fissues.apache.org%2Fjira%2Fbrowse%2FGROOVY-10026&data=04%7C01%7Ceric.milles%40thomsonreuters.com%7Cc2cfbd5838de41ec0cae08d90a5efd2f%7C62ccb8646a1a4b5d8e1c397dec1a8258%7C0%7C0%7C637552225357190799%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=iIH68xv0Lh09jdj1%2Fx8OeJMnKwZw78JeIdAWfOHCPIo%3D&reserved=0>


-----Original Message-----
From: Christopher Smith 
<chrylis+gro...@gmail.com<mailto:chrylis%2bgro...@gmail.com>>
Sent: Tuesday, April 27, 2021 6:37 PM
To: dev@groovy.apache.org<mailto: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?

Reply via email to