<html><head><style>body{font-family:Helvetica,Arial;font-size:13px}</style></head><body style="line-break:after-white-space"><div style="font-family:Helvetica,Arial;font-size:13px"><pre style="font-variant-ligatures:normal;text-decoration-style:initial;text-decoration-color:initial">> The way I like to see it is the implicit constructor is a real constructor,
<span style="font-family:Helvetica,Arial">> </span>but it is prevented from doing any field assignments, guaranteeing those
<span style="font-family:Helvetica,Arial">> </span>favorable zero-rich fields.  Giving a name to the result of that constructor
<span style="font-family:Helvetica,Arial">> </span>is possible (as you point out) but it doesn’t seem to buy much.
<span style="font-family:Helvetica,Arial">> </span>The VM could notionally assign a named value when necessary and/or
<span style="font-family:Helvetica,Arial">> </span>it could notionally call a no-op constructor when necessary:  Is there
<span style="font-family:Helvetica,Arial">> </span>much of a difference, at the level of user model?</pre></div> <div><br></div>Yes there is! …at least the way I understand it, as follows:<div><br></div><div>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’.<br> <div class="gmail_signature"></div><div class="gmail_signature">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.</div><div class="gmail_signature"><br></div><div class="gmail_signature">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.</div><div class="gmail_signature"><br></div><div class="gmail_signature">best wishes,<br><div><br></div><div>Jonathan Finn</div><div><br></div></div> <br><p class="airmail_on">On 20 January 2024 at 22:45:20, John Rose (<a href="mailto:john.r.rose@oracle.com">john.r.rose@oracle.com</a>) wrote:</p> <blockquote type="cite" class="clean_bq"><span><div><div></div><div>
<br>
<br>On 20 Jan 2024, at 11:43, Jonathan F wrote:
<br>
<br>> …
<br>> fields and array elements of type Point! are (notionally) initialised to
<br>> Point.default, not by calling the constructor, which seems more like
<br>> reality and like how other fields are set to null/0. So there’s nothing
<br>> implicit about the constructor itself; and the creation of Point.default
<br>> isn’t magic either, it’s like the creation of Point.class or enum constants
<br>> - ‘just one of those things’ that happens when a class initialises.
<br>>
<br>> If that makes sense, I’d go for the previous constructor syntax public
<br>> default Point(). Meaning simply this is the constructor used for
<br>> Point.default. Or maybe even public default-0 Point() if it’s called the
<br>> ‘zero instance’.
<br>
<br>This would not violate VM “physics” as long as the default Point value
<br>truly was always “full of zeroes only”.  But it also wouldn’t be very
<br>interesting.  OTOH, if we were to allow “interesting” Point defaults,
<br>the cost would be the disruptions I listed in my previous message.
<br>
<br>The way I like to see it is the implicit constructor is a real constructor,
<br>but it is prevented from doing any field assignments, guaranteeing those
<br>favorable zero-rich fields.  Giving a name to the result of that constructor
<br>is possible (as you point out) but it doesn’t seem to buy much.
<br>The VM could notionally assign a named value when necessary and/or
<br>it could notionally call a no-op constructor when necessary:  Is there
<br>much of a difference, at the level of user model?  It seems more
<br>economical to take an existing feature (constructors) and
<br>strength-reduce it (nop b/c no body) versus adding a point-feature
<br>for naming the constructed default.
<br>
<br>BTW, initializing a field or array element to a fixed value (zero) really
<br>is a distinct operation from assigning to a value.  The whole conversation
<br>about non-zero defaults amounts to some people wishing for the convenience
<br>of implicit assignments (of their selected values) happening invisibly
<br>wherever their value appears.  But the assignments would cost us, as I
<br>hope I demonstrated previously.
<br>
<br>Java avoids most invisible magic costs like that, when possible, so we
<br>can make our chosen invisible magic costs (object deallocation!!) be as
<br>cheap as possible.  Here’s a shorter statement identifying the invisible
<br>magic cost from a proposed default initialization feature:
<br>
<br>>> 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).
<br>
<br>> …
<br>> Even if that’s not workable, it would make me uncomfortable if
<br>> Point.default is non-null when a Point field actually defaults to null!
<br>
<br>That’s a good, er, point.  There was a time before we embraced separate
<br>nullness markers, when we thought nullness ought to be controlled by
<br>a (value) class declaration, for all the uses of the value class.
<br>In that case, Point.default would reasonably mean “the default for
<br>any Point variable”.  We needed to introduced Point.ref (you may recall)
<br>to cover other use cases.
<br>
<br>We like having it flipped it the way it is now, where Point is always
<br>a nullable, default-null type, and Point! is where the new behaviors appear.
<br>But that makes Point.default read more poorly as a result.
<br></div></div></span></blockquote></div></body></html>