Coming back to the topic of dominance for a moment before I circulate a revised 
draft spec.

Dominance is the way of pattern matching to detect dead code (meaning that code 
on the RHS of a dominated case will never be executed, provably).

Assume the example where Number dominates Integer--all values of Integer are 
going to be matched by a proceeding case, Number. This is a compile-time error. 
Additionally notice that all binding variables happen to be unused.

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


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?


Many, thanks,

Aggelos

________________________________
From: Brian Goetz <[email protected]>
Sent: 26 January 2023 20:33
To: Angelos Bimpoudis <[email protected]>; amber-spec-experts 
<[email protected]>
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 aone or more case 
patterns. 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, or aone or more case 
patterns.

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) is available at:

https://cr.openjdk.java.net/~abimpoudis/unnamed/latest/

Comments very much welcomed!
Angelos

Reply via email to