Trouble inferring type of lambda
Howard Lovatt
howard.lovatt at gmail.com
Mon Aug 23 04:34:03 PDT 2010
Thanks for the clarification, I think it *should* be a bug!
In the meantime, what is the recommended idiom for writing such a function.
-- 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