> On Aug 11, 2020, at 4:01 PM, fo...@univ-mlv.fr wrote:
> . . .
> 
> So i propose to disallow that a case with a total pattern can use an explicit 
> type with a nice message saying to use "case var" instead.
> This will effectively fix the non locality issues of the current proposal.

That specific proposal makes me slightly uneasy, if only because it forces the 
programmer to remove from the program some type information that may possibly 
be useful (to the human reader, if not also the compiler).

On the other hand, Remi’s proposal that

> From: fo...@univ-mlv.fr
> Date: August 11, 2020 at 11:42:56 AM EDT
> . . .
> A switch like this
>   switch (v) {
>       case String s: A
>       case Long l: B
>       case Object o: C
>   }
> can be seen as
>   if (v instanceof String s) {
>    A
>   } else if (v instanceof Long l) {
>    B
>   } else {
>     var o = (Object) v;   // <--- cast here
>     C
>   }


bothers me for a different reason: it seems quite strange and arbitrary that 
syntactically identical constructs (in this situation, case labels) should mean 
two very different things depending on which one happens to be the last one in 
a switch.

On the other hand, I think Remi’s point about totality being an implicit and 
non-local property that is easily undermined by code changes in another 
compilation unit is worrisome.

I think Brian’s arguments about the nature of pattern matching are very well 
thought out, and I agree that it is better for decisions about the handling of 
null to lie in the hands of the programmer, or in the design of constructs such 
as switch and instanceof, rather than be baked into the definition of pattern 
matching itself.

Putting this all together, I reach two conclusions:

(1) We can live with the current definition of instanceof, provided we make it 
clear that instanceof is not purely equivalent to pattern matching, and that 
instanceof and pattern matching can be simply defined in terms of each other.

(2) We have a real disagreement about switch, but I think the fault lies in the 
design of switch rather than with pattern matching, and the fault is this:

Sometimes when we write

        switch (v) {
                case Type1 x: A
                case Type2 y: B
                case Type3 z: C
        }

we mean for Type1 and Type 2 and Type3 to be three disparate and co-equal 
things—in which case it seems absurd for any of them to match null; but other 
times we mean for Type3 to be a catchall, in which case we do want it to match 
null if nothing before it has.  If I understand correctly, Brian suggests that 
the compiler decide which to do by analyzing whether Type3 is total; but I, the 
programmer, have no way to put in my two cents’ worth about whether I think 
Type3 is total, so I (and Remi) worry about whether the compiler and I will be 
on the same page regarding this question, especially if it is easy for 
programmer to be mistaken (yes!  it is always easy for the programmer to be 
mistaken!).

I believe some previous discussion has focused on ways to modify the _pattern_ 
to indicated either an expectation of totality or a specific way of handling 
null.  But at this point I think augmenting patterns is overkill; what we need 
(and all we need) is a modification to the syntax of switch to indicate an 
expectation of totality.  I have a modest suggestion:

        switch (v) {
                case Type1 x: A
                case Type2 y: B
                case Type3 z: C    // Type3 is not expected to be a catchall
        }

        switch (v) {
                case Type1 x: A
                case Type2 y: B
                default case Type3 z: C    // Type3 is expected to be a 
catchall; it is a static error if Type3 is not total on v,
                                                        // and Type3 will match 
null (unlike Type1 and Type2)
        }

Now, I will admit that this syntax is a wee bit delicate, because adding a 
colon might apparently change the meaning:

        switch (v) {
                case Type1 x: A
                case Type2 y: B
                default: case Type3 z: C
        }

but I believe that in situations that matter, the compiler can and will reject 
this last example on other grounds (please correct me if I am mistaken).

—Guy

Reply via email to