<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <font size="+1"><font face="monospace">Picking up on this topic:
        there's a third possibility, which I'm starting to like better. 
        <br>
        <br>
        The first two possibilities were:<br>
        <br>
         - An imperative statement (`continue`)<br>
         - A declarative clause (`when <predicate>`) on case
        labels.<br>
        <br>
        The possibly-better possibility is: instead of spending
        syntactic budget on guards (which are strictly tied to switch,
        and would then have to be extended in other places that use
        patterns, such as catch clauses), spend that budget on AND
        patterns instead.  The doc I posted this week shows that AND
        patterns are useful anyway, but here's a way we can use AND
        patterns in place of guards.  <br>
        <br>
        Thought experiment: imagine we already had static patterns.  So
        we write a static pattern.  I'm going to use a pathologically
        awful syntax just to ensure that no one is distracted by the
        syntax.  <br>
        <br>
            static<T> __pattern<br>
                      __target(T that)<br>
                      __bindings()<br>
                      __arguments(boolean expr)<br>
                      __name = "guard"<br>
                      __body {<br>
                          if (expr) <br>
                             __match_succeeds_with_bindings()<br>
                          else<br>
                             __match_does_not_succeed<br>
                      }<br>
        <br>
        The point of this is that the object model I have described
        _already_ supports guards being declared as ordinary library
        patterns, once we get to declared static patterns, if we have
        AND patterns.  Because now, a guarded pattern can be written as:<br>
        <br>
            case Foo(int x) __AND guard(x > 3): <br>
        <br>
        This has multiple big advantages: we spend our budget on a more
        general *and composible* feature (pattern conjunction) rather
        than a narrower, more ad-hoc feature (case guards in switch).  <br>
        <br>
        It is also more expressive (because of the composibility).  If
        we are already composing patterns with AND:<br>
        <br>
            case P(var x) __AND Q(var y) when (x > 0): <br>
        <br>
        we could only put the guard at the end.  But we might not want
        that -- we might want to execute the guard after the P match,
        before going on to the Q match.  If guards were just patterns,
        we'd be able to write:<br>
      </font></font><br>
    <font size="+1"><font face="monospace"><font size="+1"><font
            face="monospace">    case P(var x) __AND guard(x > 0)
            __AND Q(var y): <br>
          </font></font><br>
        and have better control over the order of matching.  Much bigger
        payoff for a pretty similiar investment.  <br>
        <br>
        But, we can't write our `guard` pattern yet in Java code.  But
        we can have built-in patterns called `true(expr)` and
        `false(expr)` which behave just like the declared patterns
        above, and our guarded case becomes:<br>
      </font></font><br>
    <font size="+1"><font face="monospace"><font size="+1"><font
            face="monospace"><font size="+1"><font face="monospace">   
                case P(var x) __AND true(x > 0) __AND Q(var y): <br>
              </font></font></font></font><br>
        Now, how to spell __AND?  We can't spell it `&&`, since
        we'd have an ambiguity with:<br>
        <br>
            if (x instanceof P && Q)<br>
        <br>
        (is that the pattern conjunction P&&Q, or `x instanceof
        P` && `Q`?)  But I think we can use `&`.  We don't
        need it much in instanceof, since we already have &&,
        but we can in switch:<br>
        <br>
            case P(var x) & true(x > 0): <br>
            case P(var x) & false(x > 0): <br>
        <br>
        <br>
        <br>
        <br>
        <br>
      </font></font>
    <div class="moz-cite-prefix">On 8/14/2020 1:20 PM, Brian Goetz
      wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:09e39b8d-2e1c-ca19-9617-dec2a3f5996e@oracle.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <blockquote type="cite"><tt><font size="+1"><br>
             - Guards.  (John, Tagir) There is acknowledgement that some
            sort of "whoops, not this case" support is needed in order
            to maintain switch as a useful construct in the face of
            richer case labels, but some disagreement about whether an
            imperative statement (e.g., continue) or a declarative guard
            (e.g., `when <predicate>`) is the right choice.  <br>
          </font></tt></blockquote>
      <tt><br>
      </tt><tt>This is probably the biggest blocking decision in front
        of us.  </tt><tt><br>
      </tt><tt><br>
      </tt><tt><font size="+1">John correctly points out that the need
          for some sort of guard is a direct consequence of making
          switch stronger; with the current meaning of switch, which is
          "which one of these is it", there's no need for backtracking,
          but as we can express richer case labels, the risk of the case
          label _not being rich enough_ starts to loom.  <br>
          <br>
          We explored rolling boolean guards into patterns themselves
          (`P && g`), which was theoretically attractive but
          turned out to not be all that great.  There are some potential
          ambiguities (even if we do something else about constant
          patterns, there are still some patterns that look like
          expressions and vice versa, making the grammar ugly here) and
          it just doesn't have that much incremental expressive power,
          since the most credible other use of patterns already
          (instanceof) has no problem conjoining additional conditions,
          because it's a boolean expression.  So this is largely about
          filling in the gaps of switch so that we don't have
          fall-off-the-cliff behaviors.  <br>
          <br>
          There are two credible approaches here:<br>
          <br>
           - An imperative statement (like `continue` or `next-case`),
          which means "whoops, fell in the wrong bucket, please
          backtrack to the dispatch";<br>
          <br>
           - A declarative clause on the case label (like `when
          <predicate>`) that qualifies whether the case is
          selected.  <br>
          <br>
          Most of the discussion so far has been on the axis of
          "continue is lower-level, and therefore better suited to be a
          language primitive" vs "the code that uses guards is easier to
          read and reason about."  Assuming we have to do one (and I
          think we do), we have three choices (one, the other, or
          both.)  I think we should step away from the either/or
          mentality and try to shine a light on what goes well, or
          badly, when we _don't_ have one or the other.  <br>
          <br>
          For example, with guards, we can express fine degrees of
          refinement in the case labels:<br>
          <br>
              case P & g1: ...<br>
              case P & g2: ...<br>
              case P & g3: ...<br>
          <br>
          but without them, we can only have one `case P`:<br>
          <br>
              case P:<br>
                  if (g1) { ... }<br>
                  else if (g2) { ... }<br>
                  else if (g3) { ... }<br>
          <br>
          My main fear of the without-guards branches is that it will be
          prohibitively hard to understand what a switch is doing,
          because the case arms will be full of imperative control-flow
          logic.  <br>
          <br>
          On the other hand, a valid concern when you have guards is
          that there will be so much logic in the guard that you won't
          be able to tell where the case label ends and where the arm
          begins.  <br>
          <br>
          <br>
        </font></tt> </blockquote>
    <br>
  </body>
</html>