JEP 305 - Pattern Matching for instanceof (Preview)
Attila Kelemen
attila.kelemen85 at gmail.com
Sat Nov 23 23:44:14 UTC 2019
One little comment on the "flow scoping" rules:
As I can see `x = y` empties the binding sets (for both T and F).
Is there a reason not to apply the same for them as if they were
written as `(x && y) || (!x && !y)`. That is, the following:
T: intersect(union(x.T, y.T), union(x.F, y.F))
F: union(intersect(x.F, y.F), intersect(x.T, y.T))
Obviously, this would apply for boolean x and y only,
and the reverse for `x != y`
Attila Kelemen <attila.kelemen85 at gmail.com> ezt írta (időpont: 2019.
nov. 23., Szo, 21:59):
>
> Thanks, I don't know how I could miss the very first link in the JEP ...
> but it actually even clears up another question I forgot to ask (i.e.,
> generic types).
>
> I guess my whole confusion came from brain failure to realize that the
> match of Scala
> (not that I know Scala that much) naturally generalize to
> `instanceof`. It looks a lot more
> sensible with the linked document (I'm especially intrigued by the
> "pattern merging" concept).
> I'm still a little sad that `x instanceof String x` is not a thing.
> Despite that it is kinda flow typing,
> it was not my hidden way to advocate for real flow typing; though my
> reasons against it
> might be different: it would probably either break backward compatibility due to
> overloading / shadowing, or introduce obscure rules for them.
>
> Anyway, I'm hoping to see the pattern matching in its full glory with records.
> Then my only wish would be to be able to create large immutable data objects in
> a non-awkward manner. Just kidding, I would bash Java for something
> else like error handling :)
>
> Attila
>
>
> Brian Goetz <brian.goetz at oracle.com> ezt írta (időpont: 2019. nov.
> 23., Szo, 20:43):
> >
> >
> >
> > > 1. Can I write `obj instanceof String obj` and shadow the original
> > > `obj` variable with the new one?
> > >
> > > It would be nice if I could, because one of my main concern
> > > with the lack of "auto-cast", is that I have to give another name
> > > to the same thing, which usually leads to lame things like
> > > `o` and `other`.
> >
> > No. It has been discussed, but so far, we are sticking with the
> > original rules about shadowing. We might consider relaxing it in the
> > future, but have ruled out doing so for now.
> >
> > While I understand the attraction of flow typing, flow typing is in fact
> > a weaker mechanism than pattern matching (though that's not obvious
> > because we're starting with the weakest form of patterns, type
> > patterns). Bundling a tiny amount of flow typing with pattern matching
> > is not likely to make the flow-typers happy, and will also serve to
> > confuse people about what pattern matching is. But when we get farther
> > down the road with pattern matching, we may review this decision.
> >
> > > 2. Is the newly declared variable final?
> > >
> > > I personally would prefer if it would be final, because then
> > > that is one less thing to worry about.
> >
> > Pattern variables are final, yes.
> >
> > > 3. Is it legal to do this kind of declaration even if the effective
> > > scope of that variable is nothing?
> > >
> > > For example, `if (obj instanceof String s || myCondition)`.
> > > As both path is reachable without `obj` being an instance of `String`.
> >
> > Yes, just as it is legal to write:
> >
> > void m() {
> > String s = "";
> > }
> >
> > We don't go out of our way to forbid declare-and-then-don't-use. Note
> > that there are still places where you might want to use `s` in the above:
> >
> > if ((obj instanceof String s && s.length() > 3) || myCondition) { ... }
> >
> > even if you don't use it in the body of the if.
> >
> > > 4. What is the limit for the compiler to figure out the scope of the variable?
> > >
> > > I was mildly surpised to see that `if (!(obj instanceof String s))`
> > > works on the else path.
> >
> > The intuitive rule is "the binding is in scope wherever it would be
> > definitely assigned, and not in scope otherwise." (We call this "flow
> > scoping.") The formal rules are sketched out here:
> >
> > http://cr.openjdk.java.net/~briangoetz/amber/pattern-semantics.html
> >
> > (and, big surprise, they bear a significant resemblance to the "definite
> > assignment" rules.)
> >
> > > But this begs the question: What is the limit of the ability to
> > > deduce the scope. If the previously mentioned expression works,
> > > then I would naively expect that javac would evaluate it this way:
> > > if the "instanceof expression" is false and the complete condition
> > > might evaluate to true with any combination of true/false for the
> > > other parts of the boolean expression, then then the newly declared
> > > variable is not in scope for the true path (similarly for the else path).
> > >
> > > If my above guess is true, then I would expect
> > > `if (!(!(obj instanceof String s) || myCondition))`
> > > to give me the `s` for the true path.
> > >
> >
> > The rules are well defined and compositional, so it doesn't really
> > matter how complex the expression you give the compiler; it will apply
> > them and determine the scope of your bindings (which might not be a
> > contiguous scope.) So the "limit" is more likely to be in your own head
> > than in the language.
> >
> >
> >
> >
More information about the compiler-dev
mailing list