Proposed: An `instanceof` expression must be able to evaluate to both true and false, otherwise it is invalid.  This rules out strongly total patterns on the RHS.  If you have a strongly total pattern, use pattern assignment instead.

Makes sense to me, but one question: would this restriction "must be able to evaluate to both true and false” be applied to _every_ `instanceof` expression, or only those that have a pattern to right of the `instanceof` keyword?  I ask because if it is applied to _every_ `instanceof` expression, this would represent an incompatible change to the behavior of `x instanceof Object`, among others.  Is it indeed the intent to make an incompatible change to the language?

Well, it's more of an aspiration than a rule -- based on what we already do.  We already use some form of this to rule out bad casts:

    String s = ...
    if (s instanceof Integer)  { ... }
    // Error, incompatible types

So here, we have a candidate instanceof that would always be false, which the compiler can derive by type analysis, and was always rejected.  It would be joined by

    if (s instanceof Object o) { ... }

because Object o is total in this case, but not

    if (s instanceof Object)

because this _can_ yield either true (if s is not null) or false (if it is.)

The reality is that the natural semantics of `instanceof <type>` and the semantics of pattern matching disagree in one small place.  But it still made more sense to extend instanceof to patterns rather than create a new "matches" operator, so we patch that small place by not allowing us to ask the confusing question.


Like with lambda parameters, I am now thinking that we gave in to the base desire to fix a past mistake, but in a way that doesn't really make the language better or safer, just more complicated.  Let's back this one out before it really bites us.

I agree with this analysis.  It does suggest that we should consider whether to extend the syntax of a type pattern from `T x` to `[final] T x`, and the syntax of a deconstruction pattern from `D(Q) [v]` to `[final] D(Q) [v]` (in the latter case, `final` may be present only if `v` is also present), so that the user can choose to mark a pattern binding variable as `final`.  (This is something that could be added right away or later.)

Exactly so.  This would further be doubling down on the pleasing pun between variable declaration and type patterns.  I don't think we need it now, but some day we might feel it is missing, and if so, there's a ready answer that requires no new bikesheds to be harmed.


Reply via email to