inference of throws type parameters in SAMs

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Oct 31 10:48:38 PDT 2012


On 31/10/12 17:37, Remi Forax wrote:
> On 10/31/2012 06:20 PM, Maurizio Cimadamore wrote:
>> On 31/10/12 17:04, Remi Forax wrote:
>>> On 10/31/2012 03:53 PM, Dan Smith wrote:
>>>> This is on the radar for inference. As you suggest, we would 
>>>> probably just choose RuntimeException in certain scenarios rather 
>>>> than using the upper bound.
>>>>
>>>> We have toyed with some more ambitious ideas for handling 
>>>> exceptions in lambda bodies, but those won't be part of Java 8.
>>>>
>>>> —Dan
>>> yes, and my fear is that if we choose something different than Object
>>> now (like RuntimeException)
>>> we will not be able to change the inference algorithm in Java 9.
>>> At least with Object as default, we know that currently the inference
>>> fails so
>>> we can provide a better one without creating incompatibilities.
>> I think Object is never a problem - for this kind of issues to show 
>> up, the inference variable must appear in the throws clause, which 
>> means it should be at least <: Throwable.
>
> yes, sorry,
> s/Object/Throwable
>
> Choosing the bound of the unconstrained variable if the variable is 
> used in a throws in not the better choice,
> but before we came with a better algorithm, it's a better choice than 
> RuntimeException because it doesn't
> hamper the use of a better algorithm in the future.
Yeah - I think that's kinda the choice ahead of us - on the one hand, if 
we add exception transparency support in the future, it seems like this 
case should be handle as a result of that work; on the other hand, 
inferring RuntimeException could be a reasonable compromise, esp. given 
that the number of incompatibilities that will occur as a result of an 
inference upgrade would be pretty low (though it's true that when 
lambdas are available inference variables in the throws clause might 
become more common...).

Maurizio
>
>>
>> Maurizio
>
> Rémi
>
>>>
>>> Rémi
>>>
>>>> On Oct 30, 2012, at 10:18 AM, Peter Levart <peter.levart at gmail.com> 
>>>> wrote:
>>>>
>>>>> Hi all,
>>>>>
>>>>> I know this has been discussed before, but a long time has passed and
>>>>> various inference algorithms have been tried in the meanwhile. So I
>>>>> would like to ask whether current state is final. For example if I 
>>>>> have
>>>>> a functional interface like the following:
>>>>>
>>>>> public interface ThrowingFactory<T, E extends Throwable> {
>>>>>       T make() throws E;
>>>>> }
>>>>>
>>>>>
>>>>> And a "hypothetical" method:
>>>>>
>>>>> public interface Stream<T> {
>>>>>       <E extends Throwable> T findFirstOrElse(ThrowingFactory<T, E>
>>>>> other) throws E;
>>>>> }
>>>>>
>>>>>
>>>>> Then the following program compiles OK:
>>>>>
>>>>>       public static void main(String... args) throws IOException
>>>>>       {
>>>>>           Stream<String> stream = null;
>>>>>
>>>>>           String first = stream.findFirstOrElse(() -> {throw new
>>>>> IOException();});
>>>>>       }
>>>>>
>>>>>
>>>>> Which indicates that the inference algorithm does it's job correctly.
>>>>> But the following program:
>>>>>
>>>>>       public static void main(String... args)
>>>>>       {
>>>>>           MyStream<String> stream = null;
>>>>>
>>>>>           String first = stream.findFirstOrElse(() -> "NO VALUE");
>>>>>       }
>>>>>
>>>>>
>>>>> Triggers the compilation failure:
>>>>>
>>>>> error: unreported exception Throwable; must be caught or declared 
>>>>> to be
>>>>> thrown
>>>>>           String first = stream.findFirstOrElse(() -> "NO VALUE");
>>>>>
>>>>>
>>>>> Regards, Peter
>>>>>
>>>>>
>>>>>
>>>>> P.S. If this worked, the controversial TypeThatMustNotBeNamed<T> 
>>>>> which
>>>>> is used as return type of 3 Stream methods could be replaced with 
>>>>> 3*3=9
>>>>> Stream methods that would more or less fit the main purpose of being
>>>>> fluent. For example, current Stream.findFirst() would expand to:
>>>>>
>>>>> public interface Stream<T> {
>>>>>       T findFirst() throws NoSuchElementException;
>>>>>       T findFirstOrElse(T other);
>>>>>       <E extends Throwable> T findFirstOrElse(ThrowingFactory<T, E>
>>>>> other) throws E;
>>>>> }
>>>>>
>>>>> Is this to much methods?
>>>>>
>>>>>
>>>>>
>>>
>>
>



More information about the lambda-dev mailing list