[External] : Re: Fwd: Two new draft pattern matching JEPs
Brian Goetz
brian.goetz at oracle.com
Fri Mar 5 16:29:17 UTC 2021
>
> The one objection I still have to grobble is one I've raised before:
> it makes it hard to imagine ever representing disjunctions as guards.
> I always bring up stuff like
>
> switch (people) {
> case Pair(Person(String name1, int age1), Person(String name2, int
> age2))
> | age1 > age2 -> name1 + " is older"
> | age2 > age1 -> name2 + " is older"
> | otherwise -> format("%s and %s are the same age", name1, name2)
> }
>
If we can assume that such "sub-switches" are routinely total on the top
pattern, I think we can do this with the tools on the table, perhaps
with some small adjustments.
Note that for deconstruction patterns, you can bind to the top-level
result. This means you can further switch on it. If we can use
grobble(e) as a case label without a pattern (which makes sense under
either the interpretation that grobble(e) is a pattern, or that it is a
feature of case), we can write your above as:
switch (people) {
case Pair(Person(String name1, int age1), Person(String name2,
int age2)) p ->
switch (p) {
case grobble(age1 > age2) -> name1 + " is older";
case grobble(age2 > age1) -> name2 + " is older";
default -> format("%s and %s are the same age", name1,
name2);
}
}
which isn't too bad. Sometimes we will want to further match on `p` (if
I was factoring cases P&Q and P&R), but in this case I'm just factoring
guards so the use of `p` here is mostly noise. We could consider
allowing you to drop the switch operand and rewrite as
switch (people) {
case Pair(Person(String name1, int age1), Person(String name2,
int age2)) ->
switch {
case grobble(age1 > age2) -> name1 + " is older";
case grobble(age2 > age1) -> name2 + " is older";
default -> format("%s and %s are the same age", name1,
name2);
}
}
in that case. A switch with no target can only contain grobble cases;
perhaps in that "case" we allow you to elide the grobbling:
switch (people) {
case Pair(Person(String name1, int age1), Person(String name2,
int age2)) ->
switch {
case age1 > age2 -> name1 + " is older";
case age2 > age1 -> name2 + " is older";
default -> format("%s and %s are the same age", name1,
name2);
}
}
All of this is switch-golf, but the point is that the use case of
factoring P&Q and P&R is one that is handled reasonably well by nested
switches already, if we had a functioning switch guard mechanism and our
sub-switches are total. If the sub-switches are total, you'd need a
real guard to capture the union of the guards, which might not be so
great, but I suspect (based on the fact that this idiom comes from
Haskell, and most piecewise decompositions in Haskell end with an
otherwise) that this is more of a corner case.
More information about the amber-spec-experts
mailing list