Type inference of parameters
Reinier Zwitserloot
reinier at zwitserloot.com
Wed Jul 7 17:20:25 PDT 2010
In general I'm looking for some clarification on the topic of resolution.
Here's how I currently believe it works, but this idea is a bit more
specific than the state-of-lambda document:
Given:
a({some lambda literal}, b, c, d), the following occurs:
1. the types of b, c, and d are calculated as usual, and for the lambda
literal, "[some sort of lambda literal]" is used as placeholder type. This
literal contains no further signature.
2. the compiler looks through the lexical stack for any methods named 'a'
that match signature ({some lambda literal}, type-of-b, type-of-c, and
type-of-d). Where a method definitely cannot match, it is discarded, but if
it can, it is tracked for the next step.
3. If there's only one method left, the lambda literal is now retrofitted
to whatever SAM type is dictated by the first parameter of the one remaining
method. If this is not possible because, for example, the lambda literal
throws checked exceptions that aren't allowed or its signature doesn't fit,
a compiler error is generated.
4. If there is more than one method left, either 4A or 4B happens. The spec
seems to lean towards 4A but I'm not sure that's its intent.
4A. The compiler emits a compiler error listing all possible alternatives.
The programmer can fix the problem by specifying the type in the lambda
literal.
4B. The compiler starts using certain known facts of the lambda literal's
signature to eliminate more methods. For example, the number of arguments of
the lambda literals is indisputable and is not subject to e.g. the recursive
type inference (which could occur if one writes "yield this;" for example).
It can do similar things for any parameters which have an explicitly
specified type. The compiler can also approach from the 'other side' so to
speak, and for example eliminate all remaining methods in the list for which
the type of the parameter where in the invocation there's the lambda literal
which are NOT sam types. This process can in theory go on forever in trying
to make both ends meet. In practice at some point the compiler stops trying,
emits a list of remaining target methods, and suggests explicitly specifying
a type, at which point resolution is exactly like java 1.6's resolution.
--Reinier Zwitserloot
On Thu, Jul 8, 2010 at 1:06 AM, maurizio cimadamore <
maurizio.cimadamore at oracle.com> wrote:
> On 07/07/2010 18:30, Stephen Colebourne wrote:
> > The latest (6 July) lambda document includes type inference of formal
> > parameters (section 4). I support this decision.
> >
> > Without this, I fear we risk creating something akin to the wide lines
> > of generics that are being simplified with the diamond operator. So
> > long as a user can choose to write the type if they wish, I suspect
> > most users will be happy.
> >
> > The exact mechanism for calculating the type inference does seem
> > tricky as Neal indicates. I'd want to see more detail on how it would
> > work in complex cases around method overloading. Like Neal, I'd want
> > type inference to work in all cases (as corner cases are what users
> > complain about).
> >
> I think an example of problematic overload resolution would be the
> following:
>
> interface SAM1 {
> void m1(Integer n) throws Exception;
> }
>
> interface SAM2 {
> void m2(Integer n);
> }
>
> void call(SAM1 sam) { ... }
> void call(SAM2 sam) { ... }
>
> call({ x -> System.out.println(x); });
>
>
> In the general case, it is not clear how the compiler should attribute
> the lambda body when there is no unique target for the SAM conversion;
> one option would be to do a trial-and-error attribution, as described in
> [1]. Instead of solving a problem by introducing another one (as Josh
> said in a separate post, Java method resolution is one of the most
> complicated parts of the language), we decided to ban this kind of
> type-inference - eventually the user will be able to disambiguate at the
> call site in a very java-ish fashion:
>
> call(SAM1 { x -> System.out.println(x); });
>
> Maurizio
>
> [1] -
>
> http://blogs.msdn.com/b/ericlippert/archive/2007/03/26/lambda-expressions-vs-anonymous-methods-part-four.aspx
>
>
>
More information about the lambda-dev
mailing list