Knocking off two more vestiges of legacy switch

forax at univ-mlv.fr forax at univ-mlv.fr
Tue Sep 13 14:51:47 UTC 2022


> From: "Dan Heidinga" <heidinga at redhat.com>
> To: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "John Rose" <john.r.rose at oracle.com>, "Brian Goetz"
> <brian.goetz at oracle.com>, "amber-spec-experts"
> <amber-spec-experts at openjdk.java.net>
> Sent: Tuesday, September 13, 2022 4:13:48 PM
> Subject: Re: Knocking off two more vestiges of legacy switch

> On Tue, Sep 13, 2022 at 10:08 AM < [ mailto:forax at univ-mlv.fr |
> forax at univ-mlv.fr ] > wrote:

>>> From: "John Rose" < [ mailto:john.r.rose at oracle.com | john.r.rose at oracle.com ] >
>>> To: "Remi Forax" < [ mailto:forax at univ-mlv.fr | forax at univ-mlv.fr ] >
>>> Cc: "Brian Goetz" < [ mailto:brian.goetz at oracle.com | brian.goetz at oracle.com ]
>>> >, "amber-spec-experts" < [ mailto:amber-spec-experts at openjdk.java.net |
>>> amber-spec-experts at openjdk.java.net ] >
>>> Sent: Tuesday, September 13, 2022 12:58:47 AM
>>> Subject: Re: Knocking off two more vestiges of legacy switch

>>> It’s too harsh to say your example shows the semantics are just wrong.

>> yes, it's more than there is inconsistencies

>>> I think they are right, but possibly incomplete. The exclusion of case 200 is
>>> the job of dead code detection logic in the language, the same kind of logic
>>> that also reports an error on "foo" instanceof List .

>>> Then there are the old murky rules that allow an integral constant like 100 to
>>> assign to byte only because 100 fits in the byte range while 200 does not. The
>>> duals of those rules will surely speak to the restriction of case 200: matching
>>> a byte.

>> The problem with that approach is that the semantics of constant patterns and
>> the semantics of primitive type patterns will be not aligned,
>> so if you have both pattern in a switch, users will spot the inconsistency.

>> something like
>> byte b = ...
>> switch(b) {
>> case 200 -> ... // does not compile, incompatible types between byte and int
>> case int i -> ... // ok, compiles
>> }

> I've been following along on this discussion and I'm not sure what the
> inconsistency here is. Remi, can you clarify?

> As a developer, the semantics here are intuitive - I can't have a (signed) byte
> that matches 200 so as John said earlier, it's clearly dead code. On the other
> hand, bytes can always be converted to an int so it makes sense that the `case
> int i` both compiles and matches to the byte. Can you expand on why users would
> find that confusing?

The error messages of javac says the types are incompatible. 

> --Dan

Rémi 

>> So i agree that we should have primitive type patterns but instead of using the
>> casting rules as model, the actual rules complemented with boolean, long, float
>> and double seems a better fit.

>> Compared to what Brian proposed, it means all primitive patterns are
>> unconditional apart unboxing if the pattern is not total (the same way
>> reference type pattern works with null).

>> Rémi

>>> On 12 Sep 2022, at 15:29, Remi Forax wrote:

>>>>> No new rules; just appeal to type patterns.
>>>> It shows that the semantics you propose for the primitive type pattern is not
>>>> the right one.

>>>> Currently, a code like this does not compile
>>>> byte b = ...
>>>> switch(b) {
>>>> case 200 -> ....
>>>> }

>>>> because 200 is not a short which is great because otherwise at runtime it will
>>>> never be reached.

>>>> But if we apply the rules above + your definition of the primitive pattern, the
>>>> code above will happily compile because it is equivalent to

>>>> byte b = ...
>>>> switch(b) {
>>>> case short s when s == 200 -> ....
>>>> }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-observers/attachments/20220913/53a04e1e/attachment.htm>


More information about the amber-spec-observers mailing list