Next up for patterns: type patterns in switch

John Rose john.r.rose at oracle.com
Fri Aug 7 23:07:45 UTC 2020


On Aug 4, 2020, at 11:11 AM, Brian Goetz <brian.goetz at oracle.com> wrote:
> 
> One thing this left open was the actual syntax of guards.  (We know its snowing in hell now, because I am actually encouraging a syntax conversation.)  

If this is only a “syntax of guards” discussion I have little to say,
except that I subjectively still find “P&&z” charming even if the
boolean z isn’t (and shouldn’t be) a pattern, and (ouch, this
will leave a mark) even though “false&&true” matches
“(Boolean)false” but “false&&false” doesn’t.

If this is a discussion of “how to guard patterns”, then see the
more substantive comment below, in context.

> ...
> The most obvious ambiguity was the obvious interpretation of constant patterns; that `0` could be the literal zero or a pattern that matches zero.  (I have since proposed we try to avoid constant patterns entirely.)

On this thread I have objected to this move, on the grounds
that it sets users up for failure with “==“ when they try refactoring
legacy constant labels to instanceof tests.  Basically, relative to
case labels and patterns, “==“ is a treacherous crutch to lean on,
in about three different ways (string identity, NaN, and NPE hazards).

> On 6/24/2020 10:44 AM, Brian Goetz wrote:
>> ...
>> An alternate to guards is to allow an imperative `continue` statement in
>> `switch`, which would mean "keep trying to match from the next label."  Given
>> the existing semantics of `continue`, this is a natural extension, but since
>> `continue` does not currently have meaning for switch, some work would have to
>> be done to disambiguate continue statements in switches enclosed in loops.  The
>> imperative version is strictly more expressive than most reasonable forms of the
>> declarative version, but users are likely to prefer the declarative version.

I still think, despite our guesses at user preferences, that
the best option is this more powerful and explicit one, even
if it sacrifices one-liner clarity for common guards:

   case P:
      if (!G)  continue switch;
      // here P matches and G is true
   case P -> {
      if (!G)  continue switch;
      // here P matches and G is true
      return …; }

Here we would spell “when G:” as “: if (!G) continue switch;”

If the extra power doesn’t cause problems, I would prefer for us
to try to live with the verbosity for a while before introducing
additional bespoke guard-for-a-pattern syntax.

Yes, it will provoke users to have to type more tokens for simple
guards.  But the provocation will be useful in the end, because
then then bloggers will begin to explain what “continuing” a
decision chain does, and that will unlock power for any users
willing to move beyond griping about syntax, i.e., most users.



More information about the amber-spec-experts mailing list