Re: Type test patterns: allow expression type to match pattern type
Anthony Vanelverdinghe
dev at anthonyv.be
Mon Apr 5 07:45:18 UTC 2021
Thanks for the instructive response and spot-on diagnosis, Brian. What would've helped me connect the dots myself in this case, is mentioning totality in the error message, something like "pattern type {1} is total on expression type {0}" (rather than the current "expression type {0} is a subtype of pattern type {1}"). But I assume this isn't possible for now, since the concept isn't actually defined in the JLS yet.
Kind regards, Anthony
On Sunday, April 04, 2021 22:25 CEST, Brian Goetz <brian.goetz at oracle.com> wrote:
>
> On 4/4/2021 1:16 PM, Anthony Vanelverdinghe wrote:
> > When using a type test pattern, the compiler gives an error if the expression type is a subtype of the pattern type.
> > While I agree that it doesn't make sense for the expression type to be a strict subtype, I believe it should be allowed to be the same type.
>
> More precisely, the compiler ensures that the pattern type is
> _applicable_ to the expression type. For reference type patterns,
> applicability means strict subtyping.
>
> You're asking if we could relax this. In theory, yes, but the choice to
> not permit total patterns in instanceof (which is what would happen if
> we allowed you use the exact type) was a deliberate choice, to work
> around the legacy behavior of `instanceof`, and to prevent bugs. And in
> fact, the bug it prevented is exactly the bug you almost made, because
> you were trying to use a total type pattern as a null check, which
> wouldn't have worked the way you wanted.
>
> For reasons that have been litigated to death, the semantics of matching
> a type pattern `T t` to a target of type `U` are:
>
> - If T is total on U, then it matches all values of U, including null;
> - If T is not total on U, then it is equivalent to `instanceof U`.
>
> This is the natural semantics for matching patterns, but it does cause a
> sharp edge relative the legacy meaning of `instanceof`. It means that:
>
> (x instanceof Object)
>
> and
>
> (x instanceof Object o)
>
> agree everywhere -- except null. Because these two are so syntactically
> similar, but would not mean the same thing, we restricted the pattern on
> the RHS of `instanceof` to patterns that _actually ask a question_. If
> we allowed `x instanceof Object o`, this would be equivalent to `true`,
> which would be surprising to many developers, including you. So this
> sharp edge was resolved in favor of "instanceof must actually ask a
> question". (There are ample other places where Java doesn't let you
> write "dumb" code, such as unreachable statements, for the same reason.)
>
> The diagnosis here, though, is that you tried to out-clever yourself by
> using a nullable pattern as a null check, instead of writing what you
> really wanted to ask -- is this thing null.)
>
> At some point, we might consider strictly non-nullable type patterns
> (e.g., `x instanceof String! s`), but we would want to do this in the
> context of a more comprehensive treatment of nullability.
>
> Looking ahead, what this really illustrates, though, is that methods
> like Map::get are the problem. Map::get pretends to be total, but
> really is partial. Really, Map::get should not be a method that returns
> a distinguished sentinel on failure, but should be a _partial pattern_
> on maps. Then you'd say something like:
>
> if (map instanceof Map.containing(k)(var v)) { ... can use v here }
>
>
>
>
>
> >
> > For example, with a `NavigableMap<String, String> map`, instead of writing:
> > if(map.higherKey("foo") != null) {
> > Files.writeString(path, map.higherKey("foo"));
> > }
> >
> > We could write:
> > if(map.higherKey("foo") instanceof String kNext) {
> > Files.writeString(path, kNext);
> > }
> >
> > Or, with a `BufferedReader in`, instead of writing:
> > String line;
> > while((line = in.readLine()) != null) { ... }
> >
> > We could write:
> > while(in.readLine() instanceof String line) { ... }
> >
> > Has this idea been considered before? If so, why was it turned down? If not, shall I file an RFE for this?
> >
> > Kind regards,
> > Anthony
> >
>
More information about the amber-dev
mailing list