The idea of implicit vs default

Jonathan F livedinsquares at gmail.com
Sat Jan 20 23:24:59 UTC 2024


> 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?


Yes there is! …at least the way I understand it, as follows:

Current story: when a field/array element is created, the type's default
value (normally null or 0) is stored in it. But for Point!, this value has
to be created by (notionally) calling its constructor, which seems so
different this process has been given the name ‘implicit’.
New story: when a field/array element is created, the type's default value
is stored in it. That’s it. And ideally, maybe this value could be
uniformly called T.default.

You’ve got a fair point that _if_ Point.default were introduced just for
this purpose then little is gained, but I thought Point.default was likely
to happen anyway? And (speculating wildly) there may be a long-term plan to
have T.default generally for any type (it feels important for generic
code), but I know how cautious the EG has to be with all this.

best wishes,

Jonathan Finn


On 20 January 2024 at 22:45:20, John Rose (john.r.rose at oracle.com) wrote:



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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-dev/attachments/20240120/d92989b2/attachment.htm>


More information about the valhalla-dev mailing list