The case for no case

Brian Goetz brian.goetz at oracle.com
Thu Jun 4 15:15:00 UTC 2020


So I think what you are saying is that you'd like `case` to be the 
distinctive prefix for "constant pattern", and use a different prefix 
for other kinds of patterns, such as instanceof.  The goal of doing so 
would be, I presume, (a) unambiguous parsing of different kinds of 
patterns and (b) giving the user visual clues for the _kind_ of match 
that follows.

Note that we'd have to mirror this into nested patterns too:

     instanceof Point(var x, case 0): ...

I like one thing and dislike one thing about this proposal.

  - Like: it gives us a way to differentiate `0` as a numeric literal 
from `0` as a constant pattern.
  - Dislike: it is asking the user to keep track of a lot of different 
ways to say what they might think of as being the same things.

I think there's a way to get the "like" and leave the dislike behind, 
and that is, let go of `0` as a constant pattern, exception in the 
special "case" of traditional constant switches.  (Most of the time, 
outside of traditional int/string switches, constant patterns will only 
show up in nested position anyway.)

What I would prefer to do here is to disambiguate the constant patterns 
more directly.  For example, we could do this with an operator, like C# has:

     case Point(== 0, == 0): ...

where `== c` is a constant pattern that matches when the target is equal 
to the constant.  (This leaves room for other relational operators, such 
as `Foo(>= 0)`, too.)

I'm not bringing this up to discuss the _specific_ syntax proposal of 
using `==` (I was going to bring that up at another time), but what I'd 
like to put on the table is that the convention of a literal being a 
pattern is probably "too clever" and having a slightly fussier way to 
say it gives us clarity at a relatively low cost.



On 6/4/2020 5:17 AM, Remi Forax wrote:
> I was reading the different tests in the pattern branch and an old idea pop up again in my head,
> given i was not able to find a mail from me explaining it, here it is.
>
> Currently Java only allow switch on constants, so we write
>    String value = ...
>    ... switch(value) {
>      case "foo" -> ...
>    }
>
> The current proposed way to extend the switch syntax to match any type is
>    Object value = ...
>    ... switch(value) {
>      case "foo" -> ...
>      case String s -> ...
>      default -> ...
>    }
>
> This seems to be a kind of natural extension, but it's not the only one.
>
> Because we want to be able to support several kinds of pattern in the future, we have to be careful about the "selector" part, the part before -> or :, of the syntax, otherwise we may not be able to express all the patterns we want.
> One simple solution is to use different keyword for different kind of patterns,
> by example, "case" for a constant pattern, "instanceof" for the type pattern, "default" the default pattern, etc
>
> using this new syntax, the same code as above will be written that way
>    Object value = ...
>    ... switch(value) {
>      case "foo" -> ...
>      instanceof String s -> ...
>      default -> ...
>    }
>
> This idea allows by example to add the "when" pattern that execute an arbitrary boolean expression,
>    var list = ...
>    ... switch(value) {
>      when list.contains(value) -> ...
>    }
>
> and to combines patterns
>    var list = ...
>    ... switch(value) {
>      instanceof String s and when !s.isEmpty() -> ....
>    }
>
> regards,
> Rémi

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20200604/9ae9a825/attachment.htm>


More information about the amber-spec-experts mailing list