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