Updated pattern match documents

Tagir Valeev amaembo at gmail.com
Tue Oct 2 04:48:17 UTC 2018


Hello!

> At least now, we only have to deal with this ambiguity in `instanceof`.  And, it might not be unreasonable to restrict the set of patterns you can put on the RHS of an `instanceof`; constant patterns on the RHS of instanceof would only be there "for completeness".  So we could restrict the grammar to be:
>
>     <id> instanceof ( <type> | <type pattern> | <deconstruction pattern> )
>
> and this problem goes away.

I tried to think how to break this. Some interesting cases could arise
if nullable type patterns are allowed for instanceof (which could be
useful sometimes):

boolean b;

void test(Object obj) {
  assert obj instanceof String? b : false;
}

Currently it's a valid assert statement with conditional expression.
Assuming that nullable patterns are allowed, this could be parsed as
nullable pattern which assigns to the fresh variable b with "false"
being an assertion message. As shadowing is prohibited, such pattern
should result in compilation error, but this is decided after parsing.
Another case when nullable pattern and ?: are mixed together:

boolean test(Object a, Object b, boolean c) {
  return a instanceof String? c ? a : b instanceof String? a : b;
}

Seems that this could be parsed in at least two different ways:

return (a instanceof String)? (c ? a : (b instanceof String? a)) : b;
and
return (a instanceof String? c) ? a : ((b instanceof String)? a : b);

Again both versions should be discarded due to prohibited shadowing,
but this occurs only after parsing.

Probably it worth taking such cases into account in advance.

With best regards,
Tagir Valeev.
On Sun, Sep 9, 2018 at 8:04 PM Brian Goetz <brian.goetz at oracle.com> wrote:
>
>
> > Seems that the new document steps away from dedicated matching
> > operator like __matches which we saw before and reuses instanceof
> > instead.
>
> Yes -- the __matches notation was always a placeholder for something,
> which might have been `instanceof` all along; we just weren't sure
> whether `instanceof` could be cleanly extended.  But, given that it can,
> this seems a pretty sensible path.
>
> > Does this mean that sole type name like String which is used in
> > instanceof currently is also a pattern?
>
> This is possible, but we don't go quite that far in the current round;
> instead, we say that instanceof can take a type or a pattern on the
> RHS.  (Related question, in the other direction: can a deconstruction
> pattern take a binding variable for the whole thing, as in `D(int x) d`?)
>
> > This could conflict with named constant. E. g.:
> >
> > class Test {
> >   static final int String = 5;
> >
> >   void test(Object obj) {
> >     if(obj instanceof String) {
> >       // obj == 5 or is a string?
> >     }
> >   }
> > }
> >
>
> We'd have this problem even more broadly if `T` were a pattern; is
>
>      case String:
>
> a type pattern, or a constant pattern?  At least now, we only have to
> deal with this ambiguity in `instanceof`.  And, it might not be
> unreasonable to restrict the set of patterns you can put on the RHS of
> an `instanceof`; constant patterns on the RHS of instanceof would only
> be there "for completeness".  So we could restrict the grammar to be:
>
>      <id> instanceof ( <type> | <type pattern> | <deconstruction pattern> )
>
> and this problem goes away.  (Saying `x instanceof 3` is kind of silly;
> you could just say `x == 3`.  Same for `var` and `_` patterns.)  And the
> result is that all these patterns are type-based, which is clearly in
> the mission of `instanceof`.
>
> If not, we have a problem where the grammar might simply accept an
> identifier, and then type checking will have to do more work before we
> know what the construct means.  (This happens too with things like
> `a.b.c`; any of those dots could be about field access, or package
> membership, or nested membership; we parse it now and sort it out later,
> according to some set of rules.)
>
>
>
>


More information about the amber-spec-experts mailing list