> De: "Brian Goetz" <brian.go...@oracle.com> > À: "Maurizio Cimadamore" <maurizio.cimadam...@oracle.com> > Cc: "valhalla-spec-experts" <valhalla-spec-experts@openjdk.java.net> > Envoyé: Lundi 15 Avril 2019 16:38:58 > Objet: Re: RefObject and ValObject
>> Let's model the value vs. reference constraint explicitly - e.g. with 'val' >> and >> 'ref' type kinds (and let's not open the can worm as to what the syntax >> should >> be, whether it should be a type anno, etc.) >> So: >> val Object ---> accepts all values >> ref Object ---> accepts all references >> any Object ---> accepts all references > We explored this sort of thing in Q world. One place where this really was > painful was what it did to generic tvar constraints; we had an entire new > algebra of constraints: > <ref T extends Bound> void m(T t) { … } Brian, val, ref and any only applies to Object. if you prefer in term of notation, let's rename ref Object to Object?, val Object to Object! and any Object to Object*, you can apply ? on any value type, Object included, you can apply ! and * only on Object. Object? is erased to Ljava/lang/Object; by the generic signature is Ljava/lang/Object/* (so it's Object for the VM and Object! for the compiler), Object! is erased to Qjav/lang/Object; Object* is erased to Ljava/lang/Object; As a bound of a type variable, Object is equivalent to Object? by backward compatibility. and <T extends Object!> void m(T t) { … } means that T is not nullable, so it's a value type. And at runtime, instead of (o instanceof Object!) one will write o.getClass().isValue() Rémi > which was ad hoc and composed terribly. This hell is _exactly_ the thing that > pushed us to Ref/ValObject as _types_ in the first place. (More of the same: > what is “ref Object”.class, and how does it differ from “any Object”.class?). >> 2) reinterpret `Object` as `any Object` >> That is, the semantics of `Object` is being redefined here - code which >> assumed >> to work with references might need to opt-in to additional constraints (e.g. >> add `ref`) in order to make sure it still work as intended. > Right. Q-world tried it the other way, and we were in utter migration hell. > There are migration cases in this direction too, but we are convinced they are > orders of magnitude fewer. >> I don't see another way out of this conundrum - other than adding a special >> rule >> (z2) which says that `new Object()` is treated specially and always has kind >> `ref`. But doing so will run afoul in almost every possible way - as soon as >> you manipulate the result of the `new` in any way (cast, assignment to >> variable >> of type `Object`, ...) you go back to `any` and you are back to a place that >> is >> incompatible with `ref Object`. > Yes, this is the cost. I have to think that given a choice between some > weirdness around ’new Object’, and dramatic, awful new kinds of types that > complicate type uses, type descriptors, reflection, etc, etc, etc, that making > the former work is going to be less painful, both for us and for users. >> Your idea of treating Object as abstract is, I believe, a sound one (which >> doesn't need any extra rule) - but we might have to figure out some story for >> anonymous inner classes of the kind `new Object() { ... }`. > Right. And, again, this can be treated as a migration issue, and we can start > warning users to migrate their source now.