Overload resolution simplification

Neal Gafter neal at gafter.com
Wed Aug 14 12:18:01 PDT 2013

On Wed, Aug 14, 2013 at 2:57 AM, Maurizio Cimadamore <
maurizio.cimadamore at oracle.com> wrote:

> I also believe (but I need Neal's help here as I'm no C# guru) that C#
> behaves very differently in the distinction between overload and inference;
> Java does a first pass of overload in which information from target type is
> not taken into account. Then there's a second round (after most specific
> method has been selected) in which target-type is injected, mostly for the
> purpose of inferring a better type (in the 'old' JLS SE 7, this used to be
> and I believe C# is the exact reverse of this - it
> does inference first, to get type-parameters out of the way (meaning that
> members for which inference fails will be exclude from set of applicable
> candidates) then it will do method selection on fully instantiated
> signature. This has subtle consequences that makes it harder to make a 1-1
> comparison - but it would seems that C# can use the target-type information
> _ahead_ of overload resolution to perform inference, thus being able to
> reject applicable candidates based on return mismatch (which Java cannot
> do).

C# does something similar to what you describe for Java.  A lambda's body
is bound to see if a result type is available even if the argument types
are not known.  That lambda result type feeds into type inference.  The
lambda body is again bound when the "full" target type is known.  Any error
in the latter binding (including result type mismatch) will cause the
candidate to fail.  All this is used just to determine whether a method is
a candidate or not, and once it is known to be a candidate the method's
type arguments (if it was generic) are fixed.  Consequently when comparing
candidates during overload resolution in C# you don't have to consider

> Last but not least, C# has a uniform treatment for primitive vs. generics
> - which means it simply won't need to amount of overloads that are common
> in the Stream API. So, again, it's hard to see whether how the expressive
> power of the two scheme can be compared because, on average, I have the
> feeling that C# users to rely less heavily on primitive overloads - which
> means most of the problems discussed here won't even apply to C# (again,
> Neal please chime in :-)).

Yes, that's right.  The .NET VM can specialize generic code based on
primitive types (or, more generally, user-defined struct types), so there
is no need to "specialize" overloads for primitives unless the
implementation is actually different.

More information about the lambda-spec-observers mailing list