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