[External] : Re: Guards redux
Brian Goetz
brian.goetz at oracle.com
Wed Mar 10 17:04:21 UTC 2021
> You nail the guard to a pattern, which is equivalent until we have
> nested patterns (and "or"/"and" patterns).
We have nested patterns already in the JEPs on the table. Where's the
problem?
> I see a lot of advantages of using && to link a guard to a pattern,
> - the symbol is heavy so there is a clear visual separation
> - without any supplementary parenthesis, && after the type pattern in
> an instanceofis the && between expression, it's almost like you can
> not have a guard with an instanceof, in practice, few instanceof will
> have a guard.
I agree few instanceof will have a guard, but users are still free to
express it that way if they like, and there's nothing wrong with that.
> I still think that using a guard inside a nested pattern is ugly but
> it can be just that, ugly. Someone may want a short-circuit in a
> deeply nested patterns .
Yes. This is not unlike other compositions; for any compositional tool,
you can overuse it. (You can arbitrarily compose boolean expressions
(or arbitrarily chain method invocations), but sometimes this is taking
it too far.)
> As i said to Gavin, i'm not at ease with using the symbol '&' in
> between patterns.
I think that this is mostly a "who moved my cheese" reaction; you're
used to thinking that & is just for bitwise operations. But, that's not
actually true; we already use & and | on types -- intersection type
casts, additional generic type bounds, multi-catch. This appeals to a
notion that & and | are boolean-like combinators on types (even if not
exposed in all places they might make sense), but this is a different
kind of combination than on integers. And yet a different kind of
combination on patterns. (In an alternate universe, we might have
different symbols for adding ints vs floats vs string concatenation, but
+ works well enough that overloading the symbols is OK -- because using
+ in this way appeals to the underlying algebraic monoid structure these
types share.)
The reason that & and | make sense on patterns, and on types, is that,
like the more familiar versions on bits, they describe a _boolean
algebra_. Boolean algebras have familiar properties such as De Morgan's
Laws. These work for types (when interpreted as value sets) as well as
bits, and they work for patterns too.
I think where you're getting hung up is that when patterns produce
bindings, and other patterns consume those bindings, we have a dataflow
dependence which would appear to undermine certain other expected
properties of a boolean algebra, such as commutativity. But, if we view
those dataflow dependencies as a separate constraint -- as we *already
do* for ints (e.g., `(x=3)&(x|4)`, is invalid when `x` is an DU int, but
valid when `x` is DA), this seeming contradiction vanishes, and is seen
to be merely a post-hoc well-formedness constraint. If the WF
constraint is satisfied, the expected properties of boolean algebras
(associativity, commutativity, absorption, etc) are satisfied too.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20210310/2dd721e4/attachment.htm>
More information about the amber-spec-experts
mailing list