Parametrized method and cyclic inference

Dan Smith daniel.smith at oracle.com
Fri Nov 2 15:19:26 PDT 2012


On Nov 2, 2012, at 10:48 AM, Remi Forax <forax at univ-mlv.fr> wrote:

> Hi guys,
> I've tried to take a big corpus of code and to refactor all inner-classes to use lambda instead.
> 
> The good news is that on 23 uses of inner classes, 20 can be retrofited to use lambdas
> because the target type is a SAM and they don't require a strong identity (this is not used).
> The bad news is that among the 20 that can be retrofited, 17 can not be retrofited using
> the syntax that doesn't specified the type of the formal parameter i.e. the natural syntax
> because the compiler complains that there is a cyclic inference.
> 
> The 17 snippets of code can be covered by 3 cases:
>  static <T> void m(T t1, T t2) {
>    // empty
>  }
> 
>  public static void main(String[] args) {
>    m(x -> 3, x -> 4);   // case 1
>    Set<Mapper<Integer, Object>> set = Collections.singleton(x -> 3);   // case 2
>    List<Mapper<Integer, Object>> list = Arrays.asList(x -> 1);  // case 3
>  }
> 
> To sumarrize, it's currently impossible to call a parametrized method with an untyped lambda,
> the inference will just choke.
> 
> I think instead that if there is a cyclic inference,
> the return type should be used to try to infer the formal parameter type of the lambda,
> at least, it will solve case 2 and 3.

Thanks!  Feedback from real code is very useful.

I'm confused about your emphasis on the implicit parameter type -- if your lambdas look like '(Integer x) -> 3', don't you still get an error?

Yes, #1 is hopeless -- there is no type anywhere to tell us what the lambdas represent.

#2 and #3 are interesting.  In general, we've nailed down a strategy for inference that depends on a target type.  But this is special.

The target type is an inference variable, T.  Note that this is _not_ a functional interface.  Everything we've done to this point has bailed out early if the target of a lambda is not a functional interface.

An alternative would be to initially hope that T will be a functional interface, wait for T to be resolved, and then go from there.  There are aspects of that that feel a little more complex than I would like, but it's probably doable.

How important are these use cases to you?

—Dan


More information about the lambda-spec-experts mailing list