Switch on several values
Brian Goetz
brian.goetz at oracle.com
Wed Sep 27 14:18:25 UTC 2023
[ dropping amber-dev ]
Yes, we've discussed this before. A switch could have multiple selector
values:
switch (a, b)
and cases could be structured similarly:
case (P, Q):
All of this isn't hard. The real question is, does it result in better
or worse code? My sense is that it look really pretty in the simple
examples, but as the number of selectors and the size of the patterns
increases, it is likely to become an unreadable soup. So that's a concern.
As an example of a "the simple cases are very pretty", I give you a
world-class FizzBuzz:
Function<Integer, String> fizzbuzz =
x -> switch (x % 3, x % 5) {
case (0, 0) -> "FizzBuzz";
case (0, _) -> "Fizz";
case (_, 0) -> "Buzz";
default -> Integer.toString(x);
};
(I might have gotten my Fizz and Buzz backwards, I didn't bother to look
it up.)
<sarcasm>
I see the appeal in "Java is the #1 language for writing FizzBuzz", but
I am not sure this is the stewardship rubric we are looking for :)
</sarcasm>
Another problem (and this one is of our own making) is that comma
already means something in cases. So
case 0, 1
means something subtly different from
case (0, 1)
which is not particularly nice. Yes, the type checker will disambiguate
for you, but we are not used to both `X` and `(X)` being valid in the
same context but meaning different things. (Worse, when you combine
these where you have multiple tuple patterns on one case, it's even more
case soup.)
So I put this one in the category of "simple enough to specify and
implement, has obvious motivating use cases, but not sure it actually
improves the language."
On 9/27/2023 10:03 AM, Remi Forax wrote:
> Hi recently Clément BOUDEREAU has reported a bug on amber-dev and unrelated to that bug,
> taking a look to the code I've noticed this
>
>
> int compareTo(final Value<T> o) {
> return switch (new Tuple<>(this, o)) {
> case Tuple<Value<T>, Value<T>>(Value.Infinite<T> _, Value.Infinite<T> _) -> 0;
> case Tuple<Value<T>, Value<T>>(Value.Infinite<T> _, Value.Fixed<T> _) -> 1;
> case Tuple<Value<T>, Value<T>>(Value.Fixed<T> _, Value.Infinite<T> _) -> -1;
> case Tuple<Value<T>, Value<T>>(Value.Fixed<T> fst, Value.Fixed<T> snd) ->
> fst.value.compareTo(snd.value);
> };
> }
>
> Here what Clément want is to match two values (here, "this" and "o") but the only way to do that is to wrap them into a pair (here named Tuple),
> Should we not provide a way to match several values natively ?
>
> Something like
>
> int compareTo(final Value<T> o) {
> return switch (this, o) {
> case (Value.Infinite<T> _, Value.Infinite<T> _) -> 0;
> case (Value.Infinite<T> _, Value.Fixed<T> _) -> 1;
> case (Value.Fixed<T> _, Value.Infinite<T> _) -> -1;
> case (Value.Fixed<T> fst, Value.Fixed<T> snd) ->
> fst.value.compareTo(snd.value);
> };
> }
>
> regards,
> Rémi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-experts/attachments/20230927/a068080a/attachment.htm>
More information about the amber-spec-experts
mailing list