The idea of implicit vs default
John Rose
john.r.rose at oracle.com
Sat Jan 20 22:45:15 UTC 2024
On 20 Jan 2024, at 11:43, Jonathan F wrote:
> …
> fields and array elements of type Point! are (notionally) initialised to
> Point.default, not by calling the constructor, which seems more like
> reality and like how other fields are set to null/0. So there’s nothing
> implicit about the constructor itself; and the creation of Point.default
> isn’t magic either, it’s like the creation of Point.class or enum constants
> - ‘just one of those things’ that happens when a class initialises.
>
> If that makes sense, I’d go for the previous constructor syntax public
> default Point(). Meaning simply this is the constructor used for
> Point.default. Or maybe even public default-0 Point() if it’s called the
> ‘zero instance’.
This would not violate VM “physics” as long as the default Point value
truly was always “full of zeroes only”. But it also wouldn’t be very
interesting. OTOH, if we were to allow “interesting” Point defaults,
the cost would be the disruptions I listed in my previous message.
The way I like to see it is the implicit constructor is a real constructor,
but it is prevented from doing any field assignments, guaranteeing those
favorable zero-rich fields. Giving a name to the result of that constructor
is possible (as you point out) but it doesn’t seem to buy much.
The VM could notionally assign a named value when necessary and/or
it could notionally call a no-op constructor when necessary: Is there
much of a difference, at the level of user model? It seems more
economical to take an existing feature (constructors) and
strength-reduce it (nop b/c no body) versus adding a point-feature
for naming the constructed default.
BTW, initializing a field or array element to a fixed value (zero) really
is a distinct operation from assigning to a value. The whole conversation
about non-zero defaults amounts to some people wishing for the convenience
of implicit assignments (of their selected values) happening invisibly
wherever their value appears. But the assignments would cost us, as I
hope I demonstrated previously.
Java avoids most invisible magic costs like that, when possible, so we
can make our chosen invisible magic costs (object deallocation!!) be as
cheap as possible. Here’s a shorter statement identifying the invisible
magic cost from a proposed default initialization feature:
>> A user-defined field default, if not zero or null, must be translated into invisible field assignments at the creation of every object or array instance, wherever such a field is part of the created object or array elements (either directly, or indirectly via a flattened value).
> …
> Even if that’s not workable, it would make me uncomfortable if
> Point.default is non-null when a Point field actually defaults to null!
That’s a good, er, point. There was a time before we embraced separate
nullness markers, when we thought nullness ought to be controlled by
a (value) class declaration, for all the uses of the value class.
In that case, Point.default would reasonably mean “the default for
any Point variable”. We needed to introduced Point.ref (you may recall)
to cover other use cases.
We like having it flipped it the way it is now, where Point is always
a nullable, default-null type, and Point! is where the new behaviors appear.
But that makes Point.default read more poorly as a result.
More information about the valhalla-dev
mailing list