Typed variants of primitives

Brian Goetz brian.goetz at oracle.com
Wed Dec 2 14:31:32 UTC 2020


> I don't think so, it all looks possible though no doubt very long
> term. The only point I'd note is that Year.default is not a valid
> year, thus more akin to null, but nulls are a whole other topic.

The topic of "inline classes with no good default" is indeed a thorny 
one, and we don't yet have a good set of recommendations here.  Possible 
moves include:

1.  Just don't make it an inline class.
2.  Pick an arbitrary default (Jan 1, 1972.)
3.  Invent a sentinel, try to make using it fail-fast (like a new kind 
of null), and make users check it (which they'll forget to do.)
4.  Use a "reference-default" inline class (one for which the unadorned 
name corresponds to the reference projection), meaning that the default 
value will truly be `null`.

None of these are great, but (4) seems to be the least-bad of the 
options identified so far.  In this world, you declare:

     __mumble_ref_mumble__ inline class Year { ... }

which, like any other inline class declaration, gives rise to three 
types: Year.ref (a true reference type, whose value set consists of 
references to instances of Year, and null), Year.val (whose value set 
consists of instances of Year), and Year.  The only difference is that 
Year becomes an alias for Year.ref rather than Year.val. So:

     Year y = date.getYear()  // might be null

What do you give up?  Well, refs are pointers, so Year is not flattened 
in layout or calling convention.  But Year.val is, so implementations 
can use Year.val for representation, and will get flattening in 
layouts.  It's not ideal, but it's a glass half-full, and the null you 
get is a real null, rather than an ad-hoc one. Work in progress.

> I asked because a question was raised to me as to whether we should
> add method overloads pre-valhalla to certain APIs in java.time.*.
>    current: LocalDate.of(int, int, int)
>    current: LocalDate.of(int, Month, int)
>    add overload in Java 17?: LocalDate.of(Year, Month, int)
>
> I think you'd suggest not to do that, but just want to be sure.

I don't see a problem with such overloads.  There's no situation in 
which overload selection would be confused by the addition of either of 
these (even in the presence of primitive widening conversions from Year 
to int; this would be like overloading m(short) against m(int), which is 
allowed.)



More information about the valhalla-dev mailing list