Value types, encapsulation, and uninitialized values

Brian Goetz brian.goetz at
Thu Oct 11 14:14:29 UTC 2018

Our story is "Codes like a class, works like an int".  A key part of 
this is that value types support the same lifecycle as objects, and the 
same ability to hide their internals.

Except, the current story falls down here, because authors must content 
with the special all-zero default value, because, unlike classes, we 
cannot guarantee that instances are the result of a constructor.  For 
some classes (e.g., Complex, Point, etc), this forced-on-you default is 
just fine, but for others (e.g., wrappers for native resources), this is 
not unlike the regrettable situation with serialization, where class 
implementations may confront instances that could not have resulted from 
a constructor.

Classes guard against this through the magic of null; an instance method 
will never have to contend with a null receiver, because by the time we 
transfer control to the method, we'd already have gotten an NPE.  Values 
do not have this protection.  While there are many things for which we 
can say "users will learn", I do not think this is one of them; if a 
class has a constructor, it will be assumed that the receiver in a 
method invocation will be on an instance that has resulted from 
construction.  I do not think we can expose the programming model as-is; 
it claims to be like classes, but in this aspect is more like structs.

So, some values (but not all) will want some sort of protection against 
uninitialized values.  One approach here would be to try to emulate 
null, by, say, injecting checks for the default value prior to 
dereferences.  Another would be to take the route C# did, and allow 
users to specify a no-arg constructor, which would customize the default 
value.  (Since both are opt-ins, we can educate users about the costs of 
selecting these tools, and users can get the benefits of flatness and 
density even if these have additional runtime costs.)  The latter route 
is less rich, but probably workable.  Both eliminate the (likely 
perennial) surprise over uninitialized values for zero-sensitive classes.

More information about the valhalla-spec-experts mailing list