On May 15, 2018, at 1:05 AM, [email protected] wrote: > > > ... > You must admit this use of supers to carry nullable values is possible, > but you are saying (I think) that you don't agree that this is useful. > > We have already decided that j.l.Object is the super that can carry null, so > yes, we do not need another one.
I see. Yes, the clever ValueRef adds mainly static checking, because it can carry a type parameter. Other than that, it is just another Object. …We could also play this move: An interface ValueRef<VT> could be defined such that, at the JVM level, the JVM enforces that (x instanceof ValueRef) if and only if (x.getClass().isValue()). The JVM would simply enforce the corresondence at class load time. It's a play I'm keeping in my pocket, which could add special runtime strength to a static typing story. > ... > In a sense, you're right, asking for nullability comes with a high cost, it's > not flattenable (otherwise you can not store null), acmp => false (it's a > value type at runtime) but you still have the fact that JITs that can spill a > nullable value type in registers which is an important case. The idea is that > even if a nullable value type escapes, the JIT doesn't have to keep it, it > can spread it into its multiple components and gather it when it escapes. > > If you take a look to Optional or LocalDate, i'm not sure the need for > flattening is that important, but being able to consider it has a value type > inside an inlining blob (inside a function of the generated assembly) is > important in term of performance when you do operation like map()/filter() or > plus*()/minus*(). This is an interesting tricky point. I'm glad it's moot for 99.9% of value types, which are the non-migrated ones. Dan's objections to non-nullable migrated arrays would be met, at very high performance cost, by making arrays of these types nullable also. What do you think about flattening arrays of these specially marked VTs (that were VBCs)? If we *don't* flatten arrays of a particular VT, then we need a special way to convey that decision to the JVM. (I wonder if Panama vector types would tolerate such a move: We mainly need in-loop optimizations, so nullability would be tolerable there, but having them boxed in arrays would be a non-starter.) > > 0. leave it alone, it's a VBC > 1. make it a proper value type, get flattening on recompile, and deal with > the null hygiene fallout > 0.1 make it a value type but mark it @VBC, no sync or acmp, no flattening > either > > but it's nullable, the semantics is simple and mostly backward compatible (== > does not work, use equals instead, do not synchronize on it) and no > allocation cost where it can be important like in loops. > in my opinion, yes, it's a trade off, but it's closer to 0.5 than 0.1. OK, I see how it is worth the experiment. It's nice that (except for the array question) it's purely in the translation strategy: The existing proposed ValueTypes attribute would (as you say) simply never mention such a marked VT. > > > The use-site choices for VTs are: > > 0. what choice? you didn't want that API point anyway > 1. Object is the untyped workaround for all your nullable needs > 1.2 clever ValueRef<VT> is your statically typed workaround for nullables > > at the cost of some oddities like what ValueRef<?> or ValueRef.class means. See above: It would mean "this is any value type". Surely that's useful? We already have reflective Class.isValue, and this would be the static type for the same concept. (You see I'm reluctant to kill this "darling"[1].) [1] https://en.wiktionary.org/wiki/kill_one%27s_darlings > > 2. Q-world: ad hoc variations everywhere between L-VT and Q-VT (cost += 1e6) > 3. some sugar like VT.BOX or an annotation for one of the previous > > and in all cases, each use-site choice means that people will have to > annotate their code to make it works like it were working before with respect > of null, so it's not really a practical option because Optional is so > widespread in the code that all the codes that contains Optional will never > be rewritten. We're in a tug-of-war here, between the goal of migratability and the prime goal of value types (mainly flattenability, of all variables). One side says "I need to flatten your variable *here*" and the other side says, "nope, not backward compatible". Maybe we're proving that migration is not really possible. We are certainly proving that migration is tricky and requires compromising various kinds of correctness (relative to the pre-migrated semantics). Ultimately, we must flatten values, except perhaps for a negligible clearly marked fraction of "compromised values" which dragged themselves away from VBC-hood, but incompletely. Ultimately we must tell the migrators to migrate with semantic changes, or not migrate. To paraphrase Yoda, "either do or do not, but about it don't cry." — John
