Switch on several values
Brian Goetz
brian.goetz at oracle.com
Wed Sep 27 14:46:04 UTC 2023
Note too that we also considered the case (heh) of a switch with _zero_
selectors, as a replacement for chains of if-else that all produce a
value to be consumed in a uniform way:
String s = switch {
case when e1 -> x;
case when e2 -> y;
default -> z;
}
This obviously doesn't have the problems I outlined with multi-selector,
but it is definitely "weirder". It seeks to capitalize on the strength
reduction of switch relative to an if-else chain, but I'm also not
convinced this one carries its weight.
On 9/27/2023 10:18 AM, Brian Goetz wrote:
> [ 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/0b7760c0/attachment-0001.htm>
More information about the amber-spec-experts
mailing list