Trouble inferring type of lambda

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Aug 23 04:59:28 PDT 2010


On 23/08/10 12:34, Howard Lovatt wrote:
> Thanks for the clarification, I think it *should* be a bug!
>
> In the meantime, what is the recommended idiom for writing such a function.
>    
You could try with:

interface SortableList<T extends Comparable<? super T>> extends List<T> {

<R, throws E> void forEach( Method1<R, T, E> method ) throws E;

}

this should do.

Maurizio

>   -- Howard.
>
> On 23 August 2010 21:15, Maurizio Cimadamore
> <maurizio.cimadamore at oracle.com>  wrote:
>    
>> On 23/08/10 12:02, Howard Lovatt wrote:
>>
>> Hi Mauritzio,
>>
>> I think it is a bug, like I said in the original post the 'return
>> type' is 'NeverReturns' not void, which should be assignable to
>> anything (including Integer). Scala and BGGA handle this case, they
>> both have a 'NeverReturns' type (Scala and BGGA Nothing).
>>
>>
>> Let me clarify - it is not a bug, according to the current spec; quoting
>> from the latest formal spec describing lambda conversion [1]:
>>
>> "A divergent lambda expression such as #(){throw new AssertionError();}
>> has no return value, and its body completes abruptly by reason of a
>> throw with an AssertionError object. For the purpose of calculating
>> the type of the lambda expression, the body of the lambda expression
>> is void."
>>
>> [1] -
>> http://mail.openjdk.java.net/pipermail/lambda-dev/attachments/20100212/af8d2cc5/attachment-0001.txt
>>
>> Maurizio
>>
>> Cheers,
>>
>>   -- Howard.
>>
>> On 23 August 2010 20:35, Maurizio Cimadamore
>> <maurizio.cimadamore at oracle.com>  wrote:
>>
>>
>> This is not a bug. You are trying to SAM convert the following lambda:
>>
>> #(x) { throws Exception(); }
>>
>> into the following target method:
>>
>> <throws E>  Integer call( Integer a1 ) throws E
>>
>> This is not possible, since the lambda expression is inferred to yield
>> 'void' (no return expression found), while the target method returns
>> Integer.
>>
>> Maurizio
>>
>>
>>
>> On 22/08/10 18:45, maurizio cimadamore wrote:
>>
>>
>> On 22/08/2010 07:09, Howard Lovatt wrote:
>>
>>
>>
>> For:
>>
>>     public interface Method1<R, A1, throws E>     { public R call( A1 a1 )
>> throws E; }
>>
>> and:
>>
>>     public<throws E>     void forEach( final Method1<Integer, Integer, E>
>> method ) throws E { ... }
>>
>> The compiler has trouble with:
>>
>>      il.forEach( #( i ) { throw new Exception(); } ); // Need to catch
>> checked exception
>>
>> Giving:
>>
>> lambdas/Main.java:34: method forEach in class IntList11 cannot be
>> applied to given types
>>         il.forEach( #( i ) { throw new Exception(); } ); // Need to
>> catch checked exception
>>           ^
>>     required: Method1<Integer,Integer,E>
>>     found: #void(?)(Exception)
>>     where E is a type-variable:
>>       E extends Exception declared in method
>> <E>forEach(Method1<Integer,Integer,E>)
>>
>> Qualifying doesn't help:
>>
>>     Method1<Integer, Integer, Exception>     #( i ) { throw new Exception();
>> }
>>
>> It gives:
>>
>> lambdas/Main.java:34: incompatible types; no instance(s) of type
>> variable(s) ? exist so that #void(?)(Exception) conforms to
>> Method1<Integer,Integer,Exception>
>>         il.forEach( Method1<Integer, Integer, Exception>     #( i ) { throw
>> new Exception(); } ); // Need to catch checked exception
>>                     ^
>>     required: Method1<Integer,Integer,Exception>
>>     found:    #void(?)(Exception)
>>
>> Is the problem that the return type isn't expressible? It isn't really
>> void, it is 'NeverReturns'.
>>
>>
>>
>>
>> Uhmm the problem here seems more related with a failure in inference of
>> the lambda parameter (the '?' that you are seeing). Again it would be
>> helpful to see the declaration of the receiver class as well as the type
>> of 'il'.
>>
>> Maurizio
>>      



More information about the lambda-dev mailing list