On Sat, Aug 27, 2016 at 4:22 AM, Jochen Theodorou <blackdrag@gmx.org> wrote:
On 27.08.2016 12:22, Paul King wrote:
I am just wondering what people's thoughts are on the different
approaches different parts of Groovy take for method resolution when
multiple methods are matched.

Given this code:

   import groovy.transform.CompileStatic

   interface FooA {}
   interface FooB {}
   class FooAB implements FooA, FooB {}
   @CompileStatic
   class TestGroovy {
     static void test() { println new TestGroovy().foo(new FooAB()) }
     def foo(FooB x) { 43 }
     def foo(FooA x) { 42 }
   }

   TestGroovy.test()

The output will be 42 because FooA comes before FooB in the implements
clause for FooAB.

I think we should orientate us at Java for this... and in Java I would expect this to fail compilation

If we leave off the @CompileStatic, their will be a runtime exception:

   groovy.lang.GroovyRuntimeException: Ambiguous method overloading for
method TestGroovy#foo

that I expect

Given this trait example:

   trait BarA { def bar() { println 42 } }
   trait BarB { def bar() { println 43 } }
   class BarAB implements BarA, BarB {}
   new BarAB().bar()

the output will be 43 because BarB comes last in the implements clause.

that is not because of method resolution, that is because of how the traits are mapped to BarAB. BarAB has in fact only one bar() method. So I do not really see a problem with this one



I agree that the differences can be surprising and confusing and that it would be very worthwhile to align the logic with Java as much as possible.  It would also be nice to be able to consolidate some of the logic where possible, it seems like the resolution is spread across several places currently.