Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-8045

Implicit closure coercion doesn't work for elements of array of functional objects



    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 2.4.7
    • 4.0.4
    • Compiler


      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 {
          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()))
                                .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


        Issue Links



              emilles Eric Milles
              ddimitrov Dimitar Dimitrov
              1 Vote for this issue
              5 Start watching this issue