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

Improve matching implicit arg closures to SAM types

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Major
    • Resolution: Fixed
    • None
    • 5.0.0-alpha-1
    • None
    • None

    Description

      When matching Closures to SAM types, we have special treatment for Closures without a formal parameter section. Such Closures may have 0 or 1 arguments, e.g.:

      foo { println 42 } // zero-arg case
      bar { println 'arg:' + it } // one-arg case
      

      Our current matching says that because of this ambiguity, we know nothing about the number of parameters, but this assumption is throwing away information: the fact that we are expecting 0 or 1 args. I'd like to propose for Groovy 5 that we match 0 or 1-arg SAMs more closely that say a 2-arg SAM for such a Closure.

      The impact of this is that there will be less ambiguity errors (or conversely, less places where we need to cast to get the correct method). It obviously doesn't help if there are both 0 and 1-arg options available, where casting would still be required.

      Example where 1 and 2-arg variants exist:

      def method1(IntUnaryOperator unary) { '1a' }
      def method1(IntBinaryOperator binary) { '1b' }
      
      // unchanged behavior
      assert method1{ x -> } == '1a'    // explicit 1 arg
      assert method1{ x, y -> } == '1b'    // explicit 2 args
      assert method1({ } as IntUnaryOperator) == '1a'    // explicit cast for implicit arg
      assert method1({ } as IntBinaryOperator) == '1b'    // explicit cast for implicit arg
      // "method1{ -> }" would remain ambiguous
      
      // proposed change: implicit arg will match Unary over Binary since Unary is the only match for 0 or 1 args
      assert method1{ } == '1a' // currently fails with Ambiguous method overloading
      

      Example where 0 and 2-arg variants exist:

      def method2(IntSupplier supplier) { '2a' }
      def method2(IntBinaryOperator binary) { '2b' }
      
      // unchanged behavior
      assert method2{ -> } == '2a'
      assert method2{ x, y -> } == '2b'
      assert method2({ } as IntSupplier) == '2a'
      assert method2({ } as IntBinaryOperator) == '2b'
      // "method2{ a -> }" would remain Ambiguous
      
      // proposed change: implicit arg will match Supplier over Binary since Unary is the only match for 0 or 1 args
      assert method2{} == '2a' // currently fails with Ambiguous method overloading
      

      Example where 0 and 1-arg variants exist:

      def method3(IntSupplier supplier) { '3a' }
      def method3(IntUnaryOperator unary) { '3b' }
      
      assert method3{ -> } == '3a'
      assert method3{ x -> } == '3b'
      assert method3({ } as IntSupplier) == '3a'
      assert method3({ } as IntUnaryOperator) == '3b'
      // "method3{ }" will remain Ambiguous since "0 or 1" matches both; error message is unchanged
      

      Example where 0, 1 and 2-arg variants exist:

      def method4(IntSupplier supplier) { '4a' }
      def method4(IntUnaryOperator unary) { '4b' }
      def method4(IntBinaryOperator binary) { '4c'  }
      
      assert method4{ -> } == '4a'
      assert method4{ x -> } == '4b'
      assert method4{ x, y -> } == '4c'
      assert method4({ } as IntSupplier) == '4a'
      assert method4({ } as IntUnaryOperator) == '4b'
      assert method4({ } as IntBinaryOperator) == '4c'
      // "method4{ }" will remain Ambiguous but error message will change from:
      //    Ambiguous method overloading [...] due to overlapping prototypes between:
      //    [interface java.util.function.IntBinaryOperator]
      //    [interface java.util.function.IntSupplier]
      //    [interface java.util.function.IntUnaryOperator]
      // to:
      //    Ambiguous method overloading [...] due to overlapping prototypes between:
      //    [interface java.util.function.IntSupplier]
      //    [interface java.util.function.IntUnaryOperator]
      // Since 0 or 1 variants will match closer than higher parameter numbers
      

      Attachments

        Issue Links

          Activity

            People

              paulk Paul King
              paulk Paul King
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: