> From: "John Rose" <[email protected]> > To: "Remi Forax" <[email protected]> > Cc: "Brian Goetz" <[email protected]>, "valhalla-spec-experts" > <[email protected]> > Sent: Thursday, July 21, 2022 9:31:00 PM > Subject: Re: The storage hint model
> On 21 Jul 2022, at 6:54, [ mailto:[email protected] | [email protected] ] > wrote: >> … >>>>> I've no idea about the performance of such kind of implementations, but >>>>> >>> >>>>> using >>>> T.flat give better control on what is flattenable or not in the >>>> implementation. >>> If we choose, we can code this trick in the design of record as well. >> You mean in the design of array ? I don't think it's wise given that the >> shape >> of the array change, but perhaps GCs can be modified to add a relocate and >> unflat operation to array. > No, I mean in the design of ArrayList (or similar generics) in the way you > sketch. If we choose we can create shape-shifting List/Map/etc. containers > which ignore the .val channel in their type args (or there’s none at all, as > you are proposing here), accept nulls, but have a better internal organization > if no nulls are encountered dynamically. I believe you need a T.val which forces to use the flat representation when the type argument of T is a value class but not a .val. > I say “if we choose” because there are reasons not to choose something that > tricky and dynamic. Library designers have more options if .val is in the type > channel. I believe that V8 has this kind of arrays for JavaScript. >>> …If some but not all of those >>> locations accept my chosen SC, my refactorings have greater friction. >> If the variable is typed by a type variable, yes. But we have decided to have >> the exact same kind of friction >> - with value class in practice because the VM is able to unmask the value >> class >> on stack but not on heap. > Here by “friction” I think you mean hidden costs when heap placement of a > value > requires separate buffering of the payload also on heap. Alert users sometimes > care about such subtleties. But (here’s the key point) users who just want the > types to connect things up properly can ignore hidden costs and have a > frictionless experience refactoring between heap and stack. That’s a win you > don’t have when every user (alert or otherwise) is confronted with SC choices > to align with type choices, during refactoring. >> - with wildcards (you have to add those pesky ? extends/super). > I have a separate proposal to patch that. It’s irregular but (again) visible > only to the very alert. A plain value class name C , when it appears as a type > argument, should be treated as sugar for ? extends C.ref . This is consistent, > I claim, with the treatment of C as sugar for C.ref in other contexts. It’s a > little piece of the magic from Dan Smith’s thesis, applied specifically to the > needs of type companions. Only when testing for subtyping relationship. Otherwise it means you can not add a C into a List of C. For me, this kind of trick are a symptom of the problem of using .val as a type channel, having two types for one value class means that most of the features that are using types in Java needs to be massaged (inference, overloading, subtyping, etc). Having a feature that requires re-interpretation of the spec everywhere should be a red flag. I'm not sure that my proposal of using storage hints is better but the cost of using .val as a type channel is scary. Rémi
