Knocking off two more vestiges of legacy switch
forax at univ-mlv.fr
forax at univ-mlv.fr
Tue Sep 13 17:31:03 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?
So my main concern stay that
String s = ...
switch(s) {
case Comparable<?> c -> ...
case Object o -> ...
}
and
long l = ...
switch(l) {
case float f -> ...
case double d -> ...
}
behave differently.
> --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/5afaec5d/attachment-0001.htm>
More information about the amber-spec-observers
mailing list