Comments/Feature Requests regarding JEP 305: Pattern Matching

Aaron Scott-Boddendijk talden at gmail.com
Thu Jul 6 20:38:31 UTC 2017


I don't know the spec well enough to be sure that there's an atomicity
guarantee over the expression for the field access of 'n.left' (and, by
extension, 'n.left.n'). Are there multiple field accesses of 'n.left' or
are we assured of resolving the field access and storing the value for use
in the expression 'n.left.n' later? For performance reasons it _might_ do
the access once, but is it a guarantee.

If there's no such guarantee, then the type of 'n.left' could change during
evaluation of the expression as a whole. Explicitly capturing this with a
binding removes any confusion about how the expression should deal with
that possibility. The fact that that this simplifies how someone has to
think about atomicity handling in this expression probably makes it
worthwhile anyway.

I presume that Kotlin treats the flow-typing as essentially a capture of
the value with newly gained type-information into a shadowing binding of
the same name (probably with narrowed scope than the shadowed binding).

--
Aaron Scott-Boddendijk


On Fri, Jul 7, 2017 at 2:10 AM, William Shackleford <wshackle at gmail.com>
wrote:

> ( The message below is being forwarded because just hitting reply before
> looks like it only went only to Maurizio Cimadamore )
>
>
> ---------- Forwarded message ----------
> From: William Shackleford <wshackle at gmail.com>
> Date: Thu, Jul 6, 2017 at 9:51 AM
> Subject: Re: Comments/Feature Requests regarding JEP 305: Pattern Matching
> To: Maurizio Cimadamore <maurizio.cimadamore at oracle.com>
>
>
>
>
> I like the guards but I would still like to avoid introducing new new
> variable names and keeping the syntax simpler.
>
> It would be nice if any expression of the form (x instanceof SomeType &&
> ((SomeType)x).field ...
>  where field is some field in SomeType but not in the original static class
> for x
>
>  could drop the unnecessary cast
>
> to be (x instanceof SomeType && x.field
>
> Then
>
> case AddNode(NegNode(IntNode(var n1)), IntNode(var n2)) && n1 == n2: ...
>
>
> would be this
>
>
> case AddNode
>         && n.left instanceof NegNode
>         && n.left.n instanceof IntNode
>         && n.right instanceof IntNode
>         && n.left.n.i == n.right.i :
>
>
> I think this makes it much easier to see all of the conditions that have to
> be true to match here.
> The same style could be used even if the classes were more general and the
> fields we needed had nothing to do with
> the constructor arguments.
> It doesn't require that I come up with any new variable names.
>
>
> -- Will
>
>
>
>
>
>
>
>
>
>
>
>
> On Wed, Jul 5, 2017 at 5:03 PM, Maurizio Cimadamore <
> maurizio.cimadamore at oracle.com> wrote:
>
> >
> >
> > On 05/07/17 21:34, William Shackleford wrote:
> >
> > In addition to being more concise:
> >  n is not both used as the positive part of the NegNode and as the input
> > parameter.
> >
> > Note that this is likely to be a bug in the original example. It is not
> > possible for a pattern binding to 'shadow' a method parameter name.
> >
> > It works with classes that have more fields/methods than constructor
> > arguments.
> > It seems to me that is better to consistently use a single syntax style
> > rather than having one for classes
> > that have only one or two fields that happen to match the constructor
> > arguments and another more
> > general style. This is especially true given that it doesn't even seem to
> > make the code more concise.
> >
> > Generally what you say is true - in many cases you will be able to write
> > things even without nested patterns.
> >
> > It is very likely that at the very least we will add some support for
> > unnamed binding (with underscore '_' ) - in the spirit of unused lambda
> > parameters (see JEP 302 [1]).
> >
> > But where I think you reach the end of the road with that approach is
> when
> > matching arbitrary expressions. Let's say you want to 'simplify' an
> > expression - that is, given an input expression, you want to construct
> > another expression that is simpler than the one in the input, by
> > recognizing things such as:
> >
> > -N + N = 0
> > 0 + N = N
> > 0 * N = 0
> > 1 * N = N
> >
> > To recognize some of those cases, you need to build more complex
> patterns;
> > for instance, for the first case you need a pattern like this:
> >
> > case AddNode(NegNode(IntNode(var n1)), IntNode(var n2)) && n1 == n2: ...
> >
> > [sidebar: '&&  n1 == n2' is what we call a _guard_ - a binary expression
> > that further controls whether a pattern matches or not]
> >
> > Writing something like the one above without nested patterns would be
> > extremely hard - you could start by checking that the outermost
> expression
> > is an AddNode, as in your example, but then you would still need 2
> dynamic
> > checks for the two nodes, and then a further dynamic check for accessing
> > the guts of the NegNode. In other words, getting at the two int values
> > would be extremely unpleasant and verbose w/o any support for nested
> > patterns.
> >
> > For simpler examples, I'm with you, simpler patterns might be just fine.
> >
> > Maurizio
> >
> > [1] - http://openjdk.java.net/jeps/302
> >
>


More information about the amber-dev mailing list