On 7/23/2020 11:52 AM, Brian Goetz wrote:
On 7/23/2020 2:38 PM, Remi Forax wrote:
On guards, they do not work well with exhaustiveness. Still not sure they are useful.

It works fine, it's just more work for the user to get right.

We induce a domination ordering on patterns.  If `T <: U`, then `T t` < `U u` (`T t` is less specific than `U u`.)  Similarly, for all guard conditions g, `P & g` < `P`.  What this says is that if you want exhaustiveness, you need an unguarded pattern somewhere, either:

     case A:
     case B & g:
     case B:              // catches B & !g
     case C:

or

     case A:
     case B & g:
     case C:
     case Object:    // catches B & !g

I understand your diffidence about guards, but I'm not sure we can do nothing.  The main reason that some sort of guards feel like a forced move (could be an imperative guard, like `continue`, but I don't think anyone would be happy with that) is that the fall-off-the-cliff behavior is so bad.  If you have a 26-arm switch, and you want the equivalent of the second of the above cases -- B-but-not-g gets shunted into the bottom clause -- you may very well have to refactor away from switch, or at least mangle your switch badly, which would be pretty bad.

Is the following what you mean by "mangle your switch badly" ?

switch (o) {
  case A: ...
  case B: do some B-ish stuff ... also, if (g) {...}
  case C: ...
  ...
  case Z: ...
  case Object: if (o instanceof B && !g) { do the B-ish non-g thing }
}


Is a guard (a) part of the `case` construct, or (b) part of the pattern operand for a `case` construct? The original mail introduced "guard expression" as "a boolean expression that conditions whether the case matches", which sounds like (a). However, the purpose of a `case` construct is to enumerate one or more possible values of the selector expression, and if a `case` construct has a post-condition `& g()` then it's not just enumerating, and it isn't a `case` construct anymore. I mean, we don't want to see guards in the `case` constructs of legacy switches, right? (`switch (i) { case 100 & g():`) So, is the answer (b) ?

Alex

Reply via email to