Composition of pattern questions
Brian Goetz
brian.goetz at oracle.com
Wed Mar 3 22:51:03 UTC 2021
> 1) What are the use cases for combined patterns beyond pattern+guard?
I presume you are asking specifically about combining patterns with the
AND combinator, since there's multiple ways to combine patterns. But,
this is sort of like asking "what are the use cases for a logical AND in
the language" -- the whole point is to give developers tools for
expressing the logic they want using regularized, combinable forms.
With patterns that operate on the totality of a target, like
`Rectangle(Point x, Point y)`, you're right that you've already tested
as much as you can about the structure of a target. And, flipping it
the other way, we can nest a Point deconstructor: `Rectangle(Point(var
x, var y), Point p2)`.
But, there are also patterns that operate by focusing on an aspect of an
aggregate. Fetching a key from a map is a good example, as is parsing
JSON/XML, as is any sort of query on a complex aggregate. As a
motivating example:
if (m instanceof (Map.withMapping("key1")(var v1) &
Map.withMapping("key2")(var v2))) { ... }
Here, we are asking if the Map matches the _combined_ pattern associated
with "has keys key1 and key2". Could we express this without combining
patterns with &? Yes, but its harder and more error-prone, because what
we want to express is the _conjunction_ of the two, and we want the
match to succeed only if both are true. If we had to test them
individually, we'd end up with a larger state space and more
opportunities to make errors.
Deconstruction patterns can also work on interfaces, so if you've got a
system where you mix lots of interfaces together, & patterns work in the
obvious way:
if (x instanceof (Fooable(FooProvider fp) & Barable(BarProvider
bp))) { ... use fp and bp ... }
> 2) Why do we need both true() and false() for guard patterns?
We don't; obviously you can derive one from the other. But if we have
only `true(e)`, people will surely ask "where is false(e)", and there
are some things that are easier to express that way.
But maybe you're asking, why call them "true" and "false" in the first
place? Without inviting a syntax design discussion here, there are a
number of reasons to propose this. They are already keywords; people
know exactly what they mean; and they are short. We could also invent a
conditional keyword (e.g., "when", "where"), but that has its
challenges, so we would prefer to use an existing keyword if there is
one that fits. (Re-using "if" is probably bad, though; it will likely
to be too hard to tell where the case ends and a statement begins.)
> 3) Are OR patterns ever going to be needed?
>
> I know there has previously been discussion around OR patterns,
> however it has currently been ruled out. It seems to me that if OR was
> permanently ruled out (a choice which limits Java's future
> development, but perhaps in an acceptable way), then there are a few
> alternate syntax options.
It is most definitely not permanently ruled out. OR patterns introduce
the complication that a binding could have _multiple_ declaration
points. This is no problem from a language design or compiler
perspective, but confusing to humans, and presents challenges for
tooling (what should the IDE do when you ask for "go to declaration"?)
Because the use cases for OR patterns are less immediate, it was a
reasonable thing to defer.
In fact, as I mentioned on the other list, the main issue here is that
most of the use cases for AND patterns are _also_ less immediate, except
we had an immediate need for guards, which leaves us with a bad choice:
expose a concept before the user base is really ready (engendering
exactly the pushback you're delivering now), or, nail yet another ad-hoc
bag on the side of switch, which will eventually become redundant
because it will be expressible using more primitive concepts.
It sounds like your vote is "bag, please"?
More information about the amber-dev
mailing list