It should be possible to type a switch expression with void

forax at univ-mlv.fr forax at univ-mlv.fr
Mon Sep 27 19:36:25 UTC 2021


> From: "Brian Goetz" <brian.goetz at oracle.com>
> To: "Remi Forax" <forax at univ-mlv.fr>, "amber-spec-experts"
> <amber-spec-experts at openjdk.java.net>
> Sent: Lundi 27 Septembre 2021 17:07:06
> Subject: Re: It should be possible to type a switch expression with void

> This is part of a larger problem, and I don't think point fixes are really the
> answer here. For this reason (and others), any sort of "type more things as
> void" is on hold for now. Here's a sketch of the motivation, which comes from
> Valhalla.

> A big part of Valhalla is unifying primitives and references. This means (yay)
> that we can say goodbye to IntPredicate and friends, since we can have:

> interface IntPredicate extends Predicate<int> { ... }

> In turn, we can also start to unify Predicate into Function:

> interface Predicate<T> extends Function<T, boolean> { ... }

> But Consumer is a roadblock, because void is not a type. We'd like to have a
> path to getting to this unification; tinkering with treating more statements as
> void expressions could make this harder.
This issue is not directly related to a switch expression allowing void expressions or not. 
If we Function<T, void> it, the only way to have the void be propagated to a functional interface type is to use a lambda expression, and lambda expressions already allow a void expression. 

So we will not make that issue worst. This issue already exists. 

Rémi 

> On 9/26/2021 3:11 PM, Remi Forax wrote:

>> There is a bad interaction between a lambda and a switch expression,
>> a lambda allows its expression to be typed void but a switch expression can not
>> be typed void,
>> so the following code does not compile

>>   sealed interface I permits A, B {}
>>   record A() {}
>>   record B() {}

>>   public Optional<A> findOneA(List<I> list) {
>>     return list.stream()
>>       .<A>mapMulti((i, consumer) -> switch(i) {
>>           case A a -> consumer.accept(a);
>>           case B b -> {}
>>       })
>>       .findFirst();
>>   }

>> This bug occurs for with any methods that takes a Consumer has parameter (so
>> stream.forEach/peek, Iterator.forEachRemaining etc).

>> The workaound is to add a pair of curly braces around the switch to transform it
>> to a switch statement.

>> For me, it should be possible to have a switch expression typed void. This is a
>> backward compatible change given that the code does not compile otherwise.

>> regards,
>> Rémi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20210927/f2152829/attachment-0001.htm>


More information about the amber-spec-experts mailing list