> On Aug 25, 2020, at 2:08 PM, Brian Goetz <brian.go...@oracle.com> wrote:
> . . .
> To pick a different syntax for purposes of exposition, suppose we had
> `total-switch` variant of `switch`. A `total-switch` would require that (a)
> the cases be at least optimistically total and (b) would insert additional
> throwing cases to patch any unhandled residue. And we could do this with any
> of the combinations that lead to X-totality -- a default clause (strongly
> total), a weakly total deconstruction pattern (residue = null), an
> optimistically total set of type patterns for sealed types (residue = { null,
> novel }), and all the more complicated ones -- distinguishing between these
> cases doesn't seem interesting. In this model, `default` just becomes a
> shorthand for "everything else, maybe with destructuring."
> On Aug 25, 2020, at 3:03 PM, Guy Steele <guy.ste...@oracle.com> wrote:
> . . .
> We can still ponder whether “default <pattern>” should issue a static error
> if the <pattern> is not total. We can furthermore ponder whether “default
> <pattern>” should require the <pattern> to be strongly total or just weakly
> total.
On reflection, I believe that in addition to having a choice of `switch` or
`total-switch`, we should indeed be a little more careful about `default`
switch labels and break them down as follows:
plain `default` as a switch label means the same as `case var _`
(which is always _strongly_ total on the type of the selector
expression)
`default <enum constant>` and `default <string constant>` and `default
<int constant>` are not permitted
`default <type pattern>` means the same thing as `case <type pattern>`
but it is a static error if the <type pattern> is not
_strongly_ total on the type of the selector expression
`default <deconstruction pattern>` means the same thing as `case
<deconstruction pattern>`
but it is a static error if the <deconstruction pattern> is not
_weakly_ total on the type of the selector expression
I think that this, in addition to your `total-switch` requirements that (a) the
set of cases be at least _optimistically_ total and (b) additional throwing
cases are inserted to patch any unhandled residue, gives a more complete and
perhaps even satisfactory solution.
The main point here is that a `default`clause should require _strong_ totality
of a type pattern but only _weak_ totality of a deconstruction pattern.
(I am aware that this set of rules would appear to allow two default clauses in
a single switch statement if the first has a <deconstruction pattern> and the
second has a <type pattern>:
switch (myBox) {
case Box(Frog f): …
default Box(Object o): …
default Box b: …
}
or
switch (myBox) {
case Box(Frog f): …
default Box(Object o): …
default: …
}
Of course, the second default clause would be chosen only for the value null.
We can have a separate debate about whether to arbitrarily forbid such usage.)