The Good Default Value

Kevin Bourrillion kevinb at google.com
Thu Jun 1 22:26:14 UTC 2023


There is one thing that I simply can never let go without comment (which
Brian had to have known :-)).


On Wed, May 31, 2023 at 11:37 AM Brian Goetz <brian.goetz at oracle.com> wrote:

### Initialization
>
> The key distinction between today's primitives and objects has to do with
> _initialization requirements_.   Primitives are designed to be _used
> uninitialized_; if we declare a field `int count`, it is reliably
> initialized to
> zero by the JVM before any code can access it.  This initial value is a
> perfectly good default, and it is not a bug to read or even increment this
> field
> before it has been explicitly assigned a value by the program, because it
> has
> _already_ been initialized to a known good value by the JVM.  The zero
> value
> pre-written by the JVM is not just a safety net; it is actually part of the
> programming model that primitives start out life with "good enough"
> defaults.
> This is part of what it means to be a primitive type.
>

Uninitialized values of primitive types do still cause bugs.

Uninitialized values of primitive types do still cause bugs!

If it scanned better I'd put it to music.

I think I understand the sense in which the phrase "it is not a bug to" is
intended above, but to me it's still an outrageous statement.

Put succinctly, I'm still unconvinced there is any such thing as a "good
default value". What I see are varying degrees of tolerable ones. Which we
tolerate why? Because performance, end of story. Oh, it might happen to be
the default you wanted, but in my mind that's just coincidence (if
admittedly not a very rare one).

As far as I know, Valhalla could *maybe* still decide to require that
non-nullable variables of value-class types be initialized
explicitly. Maybe it would complicate migration too much, I'm not sure. I
know it would require one new feature:

`new ValClass[100] (int i -> something())`

... which, importantly, must compile to the optimal code (that never
actually loops) when `something()` is literally just a call to ValClass's
implicit constructor (or is otherwise the default value for the type in
question). In case `(i -> MyImplicitlyConstructableType())` is the behavior
you want, you'd be a bit steamed to have to write it out. But just *how*
valuable is getting to skip it? I wonder.

And I would claim with some vigor that this array syntax would *always*
have been a lovely feature to have in any case. It looks to me like it
wrangles and contains the initialization gap in much the same way
try-with-resources wrangles and contains the acquire-release gap.

Maybe this is off the table for $reasons -- but then here's my point. If it
is, I claim that's a *sacrifice* we're making -- not that it was made
unnecessary by the preponderance of types with so-called "good default
values".

In other words, even if my plea here changes nothing about the feature
design (after all, it is work), I still hope merely to convince us to talk
about the feature differently than we have been, because I think it matters.

Okay. That's my highest bid. If it didn't shift anyone's view I'd really
appreciate hearing the rebuttal.

-- 
Kevin Bourrillion | Java/Kotlin Ecosystem Team | Google, Inc. |
kevinb at google.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-spec-observers/attachments/20230601/6255d87a/attachment.htm>


More information about the valhalla-spec-observers mailing list