Hi all,
just to formalize a little more my thinking about the interaction between 
(nullable) value types and erased generics.

With LW1, the VM enforces that a value type can not be null, so each time there 
is a conversion between an Object to a value type, a nullcheck is inserted.
This works great until you start to use already existing code that give a 
meaning to null, like j.u.Map.get is specified to return a V or null,
so a code like this (with Complex a value type)

  Map<String,Complex> map = ...
  Complex complex = map.get("a-key-that-does-not-exist");

throw a NPE before a user can even check if complex is null or not.

>From Java the language point of view, a solution is to have a way to express 
>that a value type can be nullable, by mandating a users to write
  Complex? complex = map.get("a-key-that-does-not-exist");
and teach javac how to do a null analysis (guaranteeing that you can not call a 
method on a Type? without a test of null first).

The question is how to translate to bytecode something like Complex?.
We have two choices, one is to teach the VM what Complex? is by adding a bit 
along with field/method descriptor the other is to erase Complex? like we erase 
T (to Object or an interface).

I believe is that we should choose the latter solution
- reifying the null information for the VM means solving the null problem of 
Java not only for value types but for every types, because if we come with a 
partial solution now, it will hamper our design choices if we want to extend it 
latter. And solving the nullablity problem is not one of the goal of valhalla, 
valhalla is hard enough, making it twice hard make no sense.
- having nullable value types reified in the VM is not enough to allow the 
migration between a reference type to a value type, programs will still choke 
on identity, synchronized, etc. But it helps for value based classes, yes, but 
it's the tail wagging the dog. There are few value based classes defined in the 
JDK and we know from the whole module 'experience' that a contract defined in 
the javadoc and not enforced by javac or the VM means nothing.
- erasure works because either a value type comes from a type parameter so it 
is already erased or it comes from a new code so it can be erased because if 
there is a signature clash due to erasure, it's in a new code so the user can 
figure out a way to workaround that.

Note2: because of separate compilations the '?' information need to be 
available in a new attribute (or in an old one by extending it) but only the 
compiler and the reflection will consume it, not the VM. 

Note2: we can also restrict further the use of '?' by disallowing to use it in 
method parameter unless it's either on a type variable or in a method 
overriding another one that uses T?, but that a language issue.

RĂ©mi

Reply via email to