> On May 10, 2018, at 8:52 AM, Brian Goetz <brian.go...@oracle.com> wrote:
> 
> Thanks for this great writeup.  I find much to agree with here, and a few 
> things to be concerned about (I’ll express the latter in a separate mail; Dan 
> touched on some of them.)  
> 
> Now that we see it, elevating from ACC_FLATTENABLE to the ValueTypes 
> attribute makes obvious sense.  The key thing to reify is whether V was a 
> value type at the time C was compiled.  This flows into many decisions within 
> C, and at the boundary of C and other V-users, so capturing it in one place 
> makes sense.  
> 
> I’ll add that this reminds me very much of loader constraints.  When class C 
> calls method D.m(P)R, we first textually match the call with m(P)R in D via 
> descriptor match, and then we additionally make sure that C and D agree on 
> any loader constraints, throwing an error if they do not.  In L-world, 
> whether C and D think V is a value or object class is another kind of 
> constraint.  At linkage time, if these constraints agree, they can use an 
> optimized protocol; if they disagree, rather than failing, the VM can 
> introduce hidden adaptation to iron out the disagreement.  

Also bridges generated by generics are naturally a place for such 
checks/adaptions from the ref world to the value world, the cast could be 
coopted to perform the null check and throw e.g. forEach'ing with a 
Consumer<Value> over a List<Value>.


> This is a big win over the use of bridges in Q-world, since the adaptors are 
> only generated at runtime when they are strictly needed, and as the ecosystem 
> gets recompiled over time to a more uniform view of V’s value-ness, will 
> steadily go away.  We saw shades of this in Albert’s first prototype of 
> heisenboxes, where the JIT compiled multiple versions of each method (if 
> needed) according to different views of value-ness, and then fit them 
> together, lego-style.  
> 
> A note on the responses:
> 
> - I think the Map.get() discussion is a red herring.  This is a signature 
> that simply makes no sense when V is a value.  We’ve looked at several 
> alternatives — optional-bearing, a pattern match (case withMapping(var v)), a 
> get-with-default, etc.  In Q-world, we observed that sometimes a method 
> doesn’t make it to the any-fied version; it becomes a restricted method that 
> only makes sense on reference types.  In L-world, we don’t necessarily have 
> “ref V” to fall back on (though we might), but there will need to be some way 
> to give Map.get() a gold watch and thank it for its service (and lament that 
> the best name has been retired from the namespace.)  
> 

Yes Map.get has to somehow retire (although i still think it represents a good 
use case of what to do at the boundary of the value and ref worlds, perhaps 
List.get is a better case to discuss in this regard) IMO that’s part of the 
hygiene we need to do to the libraries. I just don’t have a strong sense on how 
to retire this if value types and specialized generics proceed at different 
rates. We can start by deprecating it (with forRemoval? that might be tricky), 
but perhaps it requires some compiler and linkage error when used with values?

Paul.

> I’ll start a separate thread on my concerns.  
> 
> 

Reply via email to