Draft JLS Spec about unnamed patterns and variables
Remi Forax
forax at univ-mlv.fr
Thu Feb 23 18:53:21 UTC 2023
> From: "Maurizio Cimadamore" <maurizio.cimadamore at oracle.com>
> To: "Angelos Bimpoudis" <angelos.bimpoudis at oracle.com>, "Brian Goetz"
> <brian.goetz at oracle.com>, "amber-spec-experts"
> <amber-spec-experts at openjdk.java.net>
> Sent: Thursday, February 23, 2023 7:26:11 PM
> Subject: Re: Draft JLS Spec about unnamed patterns and variables
>> 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 ( [
>> https://docs.oracle.com/javase/specs/jls/se18/html/jls-14.html#jls-14.22 |
>> 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?
yes,
for me a type pattern with an unnamed variable does not introduce a pattern variable, '_' is just a notation for no variable, thus i believe, this rule does not apply.
> Cheers
> Maurizio
regards,
Rémi
>> Many, thanks,
>> Aggelos
>> From: Brian Goetz [ mailto:brian.goetz at oracle.com | <brian.goetz at oracle.com> ]
>> Sent: 26 January 2023 20:33
>> To: Angelos Bimpoudis [ mailto:angelos.bimpoudis at oracle.com |
>> <angelos.bimpoudis at oracle.com> ] ; amber-spec-experts [
>> mailto:amber-spec-experts at openjdk.java.net |
>> <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, or a one or more case
>>> pattern s . Every case constant must be either (1) the null literal, (2) a
>>> constant expression ( [
>>> https://docs.oracle.com/javase/specs/jls/se19/html/jls-15.html#jls-15.29 |
>>> 15.29 ] ), or (3) the name of an enum constant ( [
>>> https://docs.oracle.com/javase/specs/jls/se19/html/jls-8.html#jls-8.9.1 | 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, or a 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 ( [
>> https://docs.oracle.com/javase/specs/jls/se19/html/jls-15.html#jls-15.29 |
>> 15.29 ] ), or (3) the name of an enum constant ( [
>> https://docs.oracle.com/javase/specs/jls/se19/html/jls-8.html#jls-8.9.1 | 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-experts/attachments/20230223/89536198/attachment-0001.htm>
More information about the amber-spec-experts
mailing list