Currently, this seems to work better in conjunction with proposals for
AnyObj (https://github.com/lampepfl/dotty/issues/2047), so that disabling
isInstanceOf is more generally possible (though it’s not clear how to exactly combine these constructs). Current proposals keep
asInstanceOf also on
ParametricAny, but suggest that
asInstanceOf is a low-level construct:
One other refinement: When we talk about parametricity, I would reserve all methods so far in Any for AnyObj (or whatever we end up naming it), except or asInstanceOf. asInstanceOf is meant to be low-level, implementation dependent, and prone to fail. As such it is a useful escape hatch if (say) you want to have a parametric method, which nevertheless does internal hash-consing for memoization. That method could cast its argument to AnyObj and then store it in a hash map using == and hashCode.
isInstanceOf would indeed be inconsistent. That doesn’t mean we have to add extensions that cause new puzzlers—after considering all tradeoffs, rejecting an extension might be the best option.
Personally, I’d add both
ParametricAny and newtypes. Ideally I’d try to rewrite away/deprecate somehow value classes, but I doubt this is really feasible.
Erasure has to be defined, of course, but various proposals discuss a
ParametricAny type, which IIRC has no
asInstanceOf. I agree that forbidding
asInstanceOf only for
newtypes would be odd.
asInstanceOf can’t indeed be removed— you’d still have
(c: AnyRef).asInstanceOf[T] or variants available.
If enough expect
ClassCastException in any of those cases, warnings might be worthwhile. I’m not sure they should be compiler warnings instead of linter warnings, and it’s hard to see how to decide. It seems more useful to provide compiler ASTs to linters via TASTY and scala.meta, so that linters can be accurate.