Draft JLS Spec about unnamed patterns and variables

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Feb 23 18:26:11 UTC 2023


> Under this JEP this code could be rewritten blindly into:
>
> |switch (o) {       case Number _ -> 1;       case String _, Integer 
> _-> 2; } |
>
> Under the definition of dead code above, the common case that was 
> grouped together,|-> 2|, is not dead anymore. It can be reached 
> via|*case String _*, Integer _-> 2|. As a result, the code above is 
> correct. It just happens that the sub-pattern|Integer _|will never be 
> reachable. This can be a warning but the overall case is correct.
>
> An alternative interpretation would be to treat sub-patterns as "dead 
> code". Under that interpretation the second|case|of the second example 
> would be dominated because there is at least one preceding sub-pattern 
> (or whole case label with one pattern as in this case) that dominates 
> at least one of its sub-patterns (|Integer _|). That case could be 
> rejected (symmetrically to the first example). This seems restrictive 
> but also a valid direction.
>
> So, my question is what would be the pros and cons of each approach?
>
Actually, it seems to me that you can rewrite the above as follows, even 
w/o this JEP:


|switch (o) {       case Number n -> 1;       case String s, Integer i-> 
2; }|

If you do, the compiler complains, but not because `Integer i` is 
unreacheable. But simply because we have fall-through between patterns.


This is defined in 14.11.1:

> t is a compile-time error if there is a statement in a switch block 
> that consists of switch-labeled statement groups for which both of the 
> following are true:
>
> 1.
>
>     It is labeled with a switch label that introduces a pattern variable.
>
> 2.
>
>     There is a statement preceding it in the switch block and that
>     statement can complete normally (14.22
>     <https://docs.oracle.com/javase/specs/jls/se18/html/jls-14.html#jls-14.22>).
>
> This condition is required to exclude the possibility of a switch 
> labeled statement being reached for which a pattern variable declared 
> in its switch label is in scope but without the pattern matching 
> having succeeded. For example, the statement labeled by the switch 
> label supporting the type pattern |Integer i| could be reached from 
> the preceding statement group, and so the pattern variable |i| will 
> not be initialized:
>
> ||
Now, you could make a case that the above restriction is unnecessary if 
we have unnamed pattern binding variables... and _if_ you go down that 
path, yes, you do end up with an issue when it comes to dominance.


But do we want to change the fall-through restriction?


Cheers
Maurizio


>
> Many, thanks,
>
> Aggelos
>
>
> ------------------------------------------------------------------------
> *From:* Brian Goetz <brian.goetz at oracle.com>
> *Sent:* 26 January 2023 20:33
> *To:* Angelos Bimpoudis <angelos.bimpoudis at oracle.com>; 
> amber-spec-experts <amber-spec-experts at openjdk.java.net>
> *Subject:* Re: Draft JLS Spec about unnamed patterns and variables
> Small wording nit... in "an unnamed declaration can be used in place 
> of the following declarations"
>
> I'm not sure "in place of" is the right wording; I think you may just 
> want to say "in", since the grammar permits it in all of these 
> places.  (What you're really doing here is signalling that there are 
> places the grammar allows it, but the semantics do not; you are going 
> to call these out individually in the appropriate places.)
>
> Similar for the second "in place of" in this section.
>
> In 14.11.1, I might refactor the text a little further.  The second 
> sentence of the first paragraph below is about case constants only, 
> but now comes after you talk about case patterns or case constants:
>
>> A|case|label has either one or more|case|constants, ora*one or 
>> more*|case|pattern*s*. Every|case|constant must be either (1) 
>> the|null|literal, (2) a constant expression (15.29 
>> <https://docs.oracle.com/javase/specs/jls/se19/html/jls-15.html#jls-15.29>), 
>> or (3) the name of an enum constant (8.9.1 
>> <https://docs.oracle.com/javase/specs/jls/se19/html/jls-8.html#jls-8.9.1>); 
>> otherwise a compile-time error occurs. A|case|label that has 
>> a|null||case|constant may have an optional|default|.
>>
>> It is a compile-time error if for any|case|label with more than 
>> one|case|patterns, any of its|case|patterns declares one or more 
>> pattern variables.
>>
>
> I suggest:
>
> A|case|label has either one or more|case|constants, ora*one or 
> more*|case|pattern*s*.
>
> /For a case label with case constants, /every|case|constant must be 
> either (1) the|null|literal, (2) a constant expression (15.29 
> <https://docs.oracle.com/javase/specs/jls/se19/html/jls-15.html#jls-15.29>), 
> or (3) the name of an enum constant (8.9.1 
> <https://docs.oracle.com/javase/specs/jls/se19/html/jls-8.html#jls-8.9.1>); 
> otherwise a compile-time error occurs. A|case|label that has 
> a|null||case|constant may have an optional|default|.
>
> /For a case label with case patterns/, it is a compile-time error if 
> any of its|case|patterns declares one or more pattern variables.
>
> I am not sure about the definition of dominance here.  If I have:
>
>     case Integer _, String _:  A;
>     case Number _ : B;
>
> Number dominates Integer, but it doesn't dominate Integer|String.  I 
> think you mean "if at least one of pi..pn dominates *all* of the 
> patterns ri..rm, no?
>
> But I'm not even sure if this is the right formulation, because:
>
>     sealed interface I permits A, B { }
>     record A() implements I {}
>     record B() implements I {}
>
>     case A _, B _: ...
>     case I i: ...
>
> The first case label dominates I.  So I think you have to appeal to 
> exhaustiveness:
>
> "A case label with case patterns p1...pm dominates another case label 
> with case patterns q1...qm if the set of patterns { p1..pm } dominates 
> each qi", no?
>
> You probably have to slightly refactor the second statement about 
> "compile time error if dominance" accordingly.
>
>
>
>
> On 1/26/2023 5:36 AM, Angelos Bimpoudis wrote:
>> Dear experts,
>>
>> The first draft of the JLS spec about unnamed patterns and variables 
>> (https://openjdk.org/jeps/8294349 <https://openjdk.org/jeps/8294349>) 
>> is available at:
>>
>> https://cr.openjdk.java.net/~abimpoudis/unnamed/latest/ 
>> <https://cr.openjdk.java.net/~abimpoudis/unnamed/latest/>
>>
>> Comments very much welcomed!
>> Angelos
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-observers/attachments/20230223/8fd67bf9/attachment-0001.htm>


More information about the amber-spec-observers mailing list