Description
Implicit closure coercion is described here - it assumes that the closures don't need to be casted to functional types and the generic types will be inferred by the compiler.
Here is one contrived case that works from Java (this is not production code and is writen explicitly for illustration purposes):
public class GroovyAccDemo { @SafeVarargs public static <T, R> Function<T, R> ensemble(Function<T, R>... hypotheses) { return t -> Arrays.stream(hypotheses) .map(v -> v.apply(t)) .collect(Collectors.groupingBy(e -> e, Collectors.counting())) .entrySet() .stream() .max(Comparator.comparingLong(Map.Entry::getValue)) .map(Map.Entry::getKey).orElseGet(() -> null); } public static void main(String[] args) { Function<Integer, Integer> foo = ensemble( i -> i*i, i -> i+i, i -> i*i - (i+i) ); } }
Here the ensemble() method accepts a number of compatible functions and returns a single function that calls all hypotheses and returns the most popular result.
The main method illustrates that we can use the ensemble() function with Java Lambdas without any explicit casts.
If we try to do the same in Groovy, we'll get runtime error (or compile error if static compilation is enabled):
foo = GroovyAccDemo.<Integer, Integer> ensemble( { i -> i * i }, { i -> i + i }, { i -> i * i - (i + i) } );
We can make it work by explicitly coercing the closures like this:
foo = GroovyAccDemo.ensemble( { i -> i*i } as Function, { i -> i+i } as Function, { i -> i*i - (i+i ) } as Function );
This may seem as contrived use case, but it makes the use of certain API's more tedious from Groovy than from Java, which just feels wrong
Attachments
Issue Links
- is duplicated by
-
GROOVY-10529 Cannot use closures as arguments for varargs method
- Closed
- relates to
-
GROOVY-10636 STC: closure array or varargs parameter not properly type-checked
- Closed
- links to