<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <font size="+1"><font face="monospace">Let me try and summarize all
        that has been said on the Guards topic.  <br>
        <br>
        #### Background and requirements<br>
        <br>
        For `instanceof`, we don't need any sort of guard right now
        (with the patterns we have); we can already conjoin arbitrary
        boolean expressions with `&&` in all the contexts we can
        use `instanceof`, because it's a boolean expression.  (This may
        change in the future as patterns get richer.)  So we can already
        express our canonical guarded Point example with<br>
        <br>
            if (p instanceof Point(var x, var y) && x > y) {
        ... }<br>
        <br>
        with code that no one will find confusing.  <br>
        <br>
        For switch, we can't do this, because case labels are not
        boolean expressions, they're some ad-hoc sub-language.  When the
        sub-language was so limited that it could only express int and
        string constants, this wasn't a problem; there was little
        refinement needed on `case "Foo"`.  <br>
        <br>
        As we make switch more powerful, we face a problem: if the user
        drifts out of the territory of what can be expressed as case
        labels, they fall off the cliff and have to refactor their
        50-way switch into an if-else chain.  This will be a really bad
        user experience.  Some sort of escape hatch to boolean logic
        buys us insurance against this bad experience -- as long as you
        can express your non-pattern criteria with a boolean expression
        (which is pretty rich), you don't have to leave switch-land.  <br>
        <br>
        So we took as our requirement: <br>
        <br>
            Some sort of guard construct that is usable in switch is a
        forced move.<br>
        <br>
        #### Expressing guards in switch<br>
        <br>
        There are several ways to envision guards:<br>
        <br>
         - As patterns that refine other patterns (e.g., a "true"
        pattern)<br>
         - As an additional feature of "case" in switch (e.g., a "when"
        clause)<br>
         - As an imperative control-flow statement usable in "switch"
        (e.g., "continue")<br>
        <br>
        We've largely rejected the third (even though it is more
        primitive than the others), because we think the resulting code
        will be much harder to read and more error-prone.  We've bounced
        back and forth between "let's nail something on the side of
        switch" and "let's let the rising pattern tide lift all
        conditional constructs."  <br>
        <br>
        Other languages have demonstrated that guards in switch-like
        constructs are viable.<br>
        <br>
        The argument in favor of nailing something on the side of switch
        is that it is pragmatic; it is immediately understandable, it
        raises the expressivity of `switch` to where `if` already is,
        and it solves the immediate requirement we have in adding
        patterns to switch.  <br>
        <br>
        The argument against is that it is not a primitive; it is
        dominated by the option of making patterns richer (by adding
        boolean patterns), it is weak and non-compositional, and overly
        specific to switch.  (It is possible to make worse-is-better
        arguments here that we should do this anyway, but it's not
        really possible to seriously claim better, despite attempts to
        the contrary.)<br>
        <br>
      </font></font><font size="+1"><font face="monospace"><font size="+1"><font face="monospace">#### Interpreting the
            feedback<br>
            <br>
          </font></font>The JEP proposes a powerful and compositional
        approach:<br>
        <br>
         - true/false patterns that accept arbitrary boolean expressions
        (and which ignore their target);<br>
         - combining patterns with a pattern-AND combinator<br>
        <br>
        On the one hand, this is a principled, orthogonal,
        compositional, expressive, broadly applicable approach, based on
        sensible primitives, which will be usable in other contexts, and
        which anticipate future requirements and directions.  <br>
        <br>
        On the other hand, there has been a pretty powerful emotional
        reaction, which could be summarized as "sorry, we're not ready
        for this degree of generality yet with respect to patterns." 
        This emotional reaction seems to have two primary components:<br>
        <br>
         - A "who moved my cheese" reaction to the overloading of `true`
        in this way -- that `true` seems to be, in everyone's mind, a
        constant, and seeing it as a pattern is at least temporarily
        jarring.  (This may be a temporary reaction, but there's still a
        cost of burning through it.)<br>
        <br>
         - A reaction to "borrowing & from the future" -- because
        the other use cases for &-composition are not obvious or
        comfortable yet, the use of &-composition seems foreign and
        forced, and accordingly engenders a strong reaction.  <br>
        <br>
        The former (which I think is felt more acutely) could be
        addressed by taking a conditional keyword such as `when` here;
        ad-hoc "focus" research suggests the negative reaction here is
        lower, but still there.<br>
        <br>
        The latter is, I think, the more linguistically significant of
        the two; even though there is a strong motivation for &
        coming down the pike, this is not the gentle introduction to
        pattern combination that we'd like, and developer's mental
        models of patterns may not be ready.  Patterns are still new,
        and we'd like for the initial experience to make people want
        more, rather than scare them with too much up front.<br>
        <br>
        #### Options<br>
        <br>
        I suspect that we'd get a lot of mileage out of just renaming
        true to something like "when"; it avoids the "but that's not
        what true is" reaction, and is readable enough:<br>
        <br>
            case Foo(var x) & when(x > 0):<br>
        <br>
        but I think it will still be perceived as "glass half empty",
        with lots of "why do I need the &" reactions.  And, in the
        trivial (but likely quite common, at least initially) case of
        one pattern and one guard, the answers are not likely to be very
        satisfying, no matter how solidly grounded in reality, because
        the generality of the compositional approach is not yet obvious
        enough to those seeing patterns for the first time.  <br>
        <br>
        I am not compelled by the direction of "just add guards to
        switch and be done with it", because that's a job we're going to
        have to re-do later.  But I think there's a small tweak which
        may help a lot: do that job now, with only a small shadow of
        lasting damage:<br>
        <br>
         - Expose `grobble(expr)` clauses as an option on pattern switch
        cases;<br>
        <br>
         - When we introduce & combination (which can be deferred if
        we have a switch guard now), plan for a `grobble(e)` pattern. 
        At that point, <br>
        <br>
            case Foo(var x) grobble(x > 0): <br>
        <br>
        is revealed to be sugar for<br>
      </font></font><br>
    <font size="+1"><font face="monospace"><font size="+1"><font face="monospace">    case Foo(var x) & grobble(x >
            0): <br>
            <br>
            As as bonus, we can use grobble by itself in pattern
            switches to incorporate non-target criteria:<br>
            <br>
                case grobble(e): <br>
            <br>
            which is later revealed to be sugar for:<br>
            <br>
                case Foo(var _) & grobble(e): <br>
            <br>
            The downside here is that in the long run, we have something
            like the C-style array declarations; in the trivial case of
            a single pattern with a guard, you can leave in the & or
            leave it out, not unlike declaring `int[] x` vs `int x[]`. 
            Like the "transitional" (but in fact permanent) sop of
            C-style declarations, the "optional &" will surely
            become an impediment ("why can I leave it out here, but not
            there, that's inconsistent").  <br>
            <br>
            All that said, this is probably an acceptable
            worse-is-better direction, where in the short term users are
            not forced to confront a model </font></font></font></font><font size="+1"><font face="monospace"><font size="+1"><font face="monospace">that they don't yet understand (or borrow
            concepts from the future), with a path to
            sort-of-almost-unification in the future that is probably
            acceptable.<br>
            <br>
            <br>
          </font></font></font></font>
  </body>
</html>