----- Mail original ----- > De: "Christopher Smith" <chrylis+gro...@gmail.com> > À: "dev" <dev@groovy.apache.org> > Envoyé: Mercredi 28 Avril 2021 01:37:14 > Objet: 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? It may be simpler to have a conversion from any instance of a functional interface to a Closure, with closure.call() calling the abstract method of the functional interface. This will require to check at runtime if a class implement a functional interface, to wrap the instance in a Closure. It would be cool if the annotation @FunctionalInterface was declared with a retention RUNTIME, so the check to know if an instance is a lambda or not will be easy. But wait, it's already the case, someone thought about that in the lambda expert group :) Rémi