The Good Default Value

Kevin Bourrillion kevinb at google.com
Fri Jun 2 21:21:17 UTC 2023


On Fri, Jun 2, 2023 at 10:31 AM Brian Goetz <brian.goetz at oracle.com> wrote:

> I'm trying to establish that there's never anything actually *good* about
> default initialization; that at the very best it's "harmless and very
> slightly convenient", no more. A typing saver in exchange for bug risk.
> Notably it's at its most harmless for nullable types, which are the more
> likely ones to blow up outright when used uninitialized. But those aren't
> the cases this thread is focusing on.
>
>
> OK, let me zoom out.  Primitives (and B3) support implicit construction
> (with zero default values) *so that* they can be effectively represented in
> memory.  While neither C nor Java 1.0 spelled this out, there is an obvious
> cost to representing numerics with an indirection, and the initialization
> safety of null would have effectively required indirection.  So numerics in
> C and primitives in Java (and going forward, B3 in Java) support default
> initialization not because the default is *semantically great*, but because
> it's the pragmatic choice that gets us the memory layout we want.
>
> I think when you say "good" wrt default values, you're speaking purely
> about programming-model considerations (i.e., convenience, readability,
> safety), and when I say "good" wrt default values, I'm speaking about all
> of those *plus* the memory layout consequences.
>

I low key suspect you might have that impression mostly because it's what
you *expect* from me. Or I might have communicated badly, or am missing
something obvious (wouldn't be the first time today).

I was hypothesizing that we could have both. I've floated the idea of
requiring explicit initialization, but did acknowledge that something would
absolutely *have* to optimize a literal `new MyVal[1000] (i ->
MyVal.default)` (handwave syntax) to the same thing `new MyVal[1000]` would
do (if allowed). I wouldn't have it otherwise. I *think* that bridges this
perceived gap?

If that's impossible, this whole thread basically goes away.

Now the reaction I'd *expect* is "no one wants to have to write that". But
I think that actually supports my main point: that this is a convenience
argument, not that that default is in any intrinsic way "good". Then I
guess my secondary claim is that it's actually *mild* convenience at that.

I'm wondering why we shouldn't require fields of non-nullable value-class
> types to be explicitly initialized. `Complex x = new Complex(0, 0)` or
> `Complex x = new Complex()`. I'll stipulate "people would grumble" as
> self-evident.
>
> For B1!/B2! fields, this almost a forced move, as otherwise an object will
> be created with ! fields that have null in them.  For B3! fields, given
> that the whole distinction between B3 and B2 is about implicit
> construction, this seems like it might be counterproductive, and it will be
> another seam between primitives and B3!.
>

Making primitives more special is bad, it's true. But for what it's worth,
from my experiences, what I'm saying does apply to primitives too: `new
int[100] { 0 }` is just as superior to `new int[100]` as with the MyVal
case above. The only difference (in my magic-wand universe here) is that
the int case can draw only a warning, for $someLongPeriodOfTime, before the
seam goes away. I think a seam with an expiration date is *already* a
less-bad kind of a seam just for that fact, even if that date is *very* far
in the future.

I realize this is a hard pill to swallow, and I can't be surprised if my
full argument doesn't carry. But even given today's exact design, I have to
object to the *way* it keeps being justified.

Did this help?

-- 
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/20230602/62affd1a/attachment.htm>


More information about the valhalla-spec-observers mailing list