<div dir="ltr"><div dir="ltr">On Wed, Feb 8, 2023 at 7:16 AM Brian Goetz <<a href="mailto:brian.goetz@oracle.com">brian.goetz@oracle.com</a>> wrote:<br></div><div dir="ltr"><br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">"Sensible defaults" has been a long-standing challenge. The VM has a <br>
very, very strong bias towards the default state of memory being all <br>
zeroes. It is convenient that this yields sensible defaults for our <br>
primitives (numeric zero) and references (null pointers). Nullable types <br>
have a good zero default: null. "Well behaved" value types like Complex <br>
have a good zero default: zero.</blockquote><div><br></div><div>To get my stance (that you already know) onto the list: for a nullable type, null is immeasurably *better* than just a "sensible default"; it is *no default at all*. Information is simply missing, never guessed at. Null is a wonderful thing (it's only a null-oblivious type system that makes us think it isn't).</div><div><br></div><div>Whatever the all-zeroes value is worth for value types is much less clear-cut. (hey, if zero is such a great default, why don't we initialize locals to it too?)</div><div><br></div><div>A type that models (some approximation of) an algebraic ring is the Very Special Best Use Case. It is blessed to have two clearly-most-common reduction operations, and a single value (zero) that both serves as the identity for one of those operations, and is utterly destructive to the other (i.e., multiplying onto a value without initializing it to 1 first will at least make your bug clearly noticeable!). I feel these discussions over-rotate toward those special cases. Those numeric use cases might be the most *motivating* ones, but that doesn't mean they're necessarily the most common or the most "important" (for some definition).</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">That is: if your zero default is bad, you need null as a default. This <br>
is one of the central reasons for having Bucket 2. (Spoiler: I don't <br>
like bucket 2.)<br></blockquote><div><br></div><div>And, of course, I (heart) bucket 2. :-) We (Google) expect to send out migration changelists throughout our internal codebase to make every bucket 1 class into a bucket 2 class that we can (mainly not the mutable ones, which our codebase is biased against anyway). So I guess we have a gap here!</div><div><br></div><div>Refresher for observers: "Bucket 1" is what every class and class-based type is today. Bucket 2 is the same exact thing but without identity. Without identity, you have a number of restrictions -- no non-final fields, no locking, etc. Of course, a whole ton of classes never wanted those things in the first place. Bucket 3 used to refer to an "inlinable" value type in the vein of `int`, but after all the latest changes that have been discussed, it now looks to me like B2 vs. B3 is a decision for the *runtime* to make, not me. (And that's outstanding!)</div><div><br></div><div>But as regards B1 vs B2 I think it's as pure a case of a backward default as any. If you want identity, of course you can have it. If you want your field to be reassignable or your nested class to have a hidden reference to an instance of the enclosing class, you can have these things. But every reasonable compendium of best-practice advice for Java will tell you to make nested classes static and fields final until you need otherwise. Never let your desire for brevity outweigh the more important considerations. Why would this case be different, I have to wonder?</div><div><br></div><div>Using B2 by default is both principled and practical. It's how we *defer to the runtime* to make performance decisions for us. And we really really like doing that.</div><div><br></div><div>And none of this has anything to do with being a special kind of class like `Complex`.</div><div><br></div></div>--<br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div style="line-height:1.5em;padding-top:10px;margin-top:10px;color:rgb(85,85,85);font-family:sans-serif"><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(213,15,37);padding-top:2px;margin-top:2px">Kevin Bourrillion |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(51,105,232);padding-top:2px;margin-top:2px"> Java Librarian |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(0,153,57);padding-top:2px;margin-top:2px"> Google, Inc. |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(238,178,17);padding-top:2px;margin-top:2px"> <a href="mailto:kevinb@google.com" target="_blank">kevinb@google.com</a></span></div></div></div></div></div></div></div></div>