On Aug 4, 2020, at 11:11 AM, Brian Goetz <brian.go...@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.