On Mar 1, 2019, at 3:47 AM, Maurizio Cimadamore <maurizio.cimadam...@oracle.com> wrote: > > From a technical perspective I don't think there's any issue. You get condy > semantics, which, as you say, is well defined w.r.t. cycles and laziness etc. > > From a language perspective I see an issue if we expect, as we said, that > most people will just jump in and replace 'static' with 'lazy-static'. That > is gonna have all sorts of behavioral incompatibilities.
The first time someone gets an error because the value of the lazy-static is null, they will say "those idiots", etc. Whereas we want them to think of adding laziness as a simple, foolproof way to get certain kinds of performance improvements. This is a good point, and may overcome my arguments. It will push the friction forward in time, to the place where we add non-static lazies; at that point we will have a less pleasant choice between transactional memory and reserving the value I am asking we reserve *now*. (BTE, this is a classic example of something that looks great from the VM looking upward doesn't look so great from the user model looking downward.) So, I want to defend my proposal a little more, not only by saying we'll pay a cost later if we don't reserve the value now, but also by noting that your point about "all sorts of behavioral incompatibilities" applies more evenly than you may think, to both proposals (reserve a value, vs. don't reserve). Even if you allow the full range of values, including null, there will be all sorts of more subtle behavioral incompatibilities just from changing the order in which statics are initialized, and (what's more) making the order dynamically data dependent. The bugs that folks will run into from "going lazy" will be bootstrap ordering bugs, causing null pointer exceptions (typically) when one initializer needs access to a non-lazily initialized static in some other class. Bootstrap errors happen all the time when there are delicate inter-class initialization dependencies. Today we see it when static initializers recurse into themselves via another class. Tomorrow we will see it whenever there is a mix of lazy and non-lazy initialization. So, I don't buy that non-reservation of null is going to especially improve the user experience. It will remove one moderately sharp edge, leaving some sharper ones. I'm saying the reserved value is "moderately" sharp, because it is relatively easy to diagnose, compared with bootstrap ordering bugs, which are always non-local in nature. And, just to repeat another bit: We have already bitten the "no nulls" bullet with Optional. We are telling users that, for certain constructs, nulls are out of policy. That too could cause "all sorts of incompatibilities", making it hard to refactor to use the new feature (Optionals). So it feels like a defensible move here also. "Lazies are a language supported form of optionals which automatically change state from empty. You can't put nulls in them." What's hard about that? Especially if we make reflection and/or method handle versions which return an actual Optional if the user wants to do a non-triggering sense of the state. Anyway, on balance, I'd still prefer to make lazies like optionals, and then continue to align them that way when we get to non-static lazies and (if we go there) use-site lazies. I didn't say "if we go there" for non-static lazies because they are so freaking useful *today*, under the disguise of @Stable. We'll want to go there. HTH — John