On Jun 29, 2021, at 2:36 PM, Kevin Bourrillion <kev...@google.com<mailto:kev...@google.com>> wrote:
Speaking of orthogonality, there *is* an open question about how we interpret <invalid>, and this is orthogonal to the question of whether <invalid> should be the "default default". We've talked about: - It's interchangeable with null - It's null-like (i.e., detected on member access), but distinct - It's a separate concept, and it is an error to ever read it from fields/arrays All still on the table. Oh. Yeah, if you look at all the work we've all poured into how we manage null and its attendant risks, and ongoing work (perhaps charitably assume JSpecify will be successful! :-)), then it's kiiiind of a disaster if there's suddenly a second kind of nullness. #nonewnulls BTW, the combination of #nonewnulls (a principle I whole-heartedly favor) and “it is an error to ever read it” pencils out some capability to define containers of nullable types but which reject nulls in some way. (Perhaps a subtle way: Perhaps the container starts out null but cannot be read until a different initial value is written.) Such containers would resemble, in certain ways, containers for lazily-computed values. (I.e., they have a dynamically-distinguished undefined state, and they cannot return to that state having left it.) OTOH, a container for a lazily-computed *nullable* value would, in fact, require a second sentinel, not null, to denote the unbound state; making that sentinel escape would create a #newnull, which would be bad. Not sure how to square this circle yet. Another random side-point, this time about `withfield`: It is IMO impractical to perform default exclusion (null detection) for field assignments in primitive class constructors, because the default-ness of `this` is a complicated dynamic property of all the fields together. As a constructor executes, it may temporarily revert `this` to the default value if it zeroes out a field. So the `withfield` instruction should *not* perform default exclusion on `this`. (Of course an excluded default would get checked for on exit from the constructor.) A similar point goes for `getfield`, perhaps, though less strongly, because the Java language would not use it. But the JVMS should probably attach default exclusion either to both `withfield` and `getfield` or neither. This suggests that only method invocations would perform default exclusion. Which reminds me: I think we should allow calls to methods on `this` inside a constructor. (Do we?) A clean way to statically exclude incomplete values of `this` would be to outlaw such self-calls until all final fields are definitely assigned. The current language (for identity classes) computes this point (of complete field assignment) in order to enforce the rule that the constructor cannot return until all final fields have been definitely assigned. For identity classes it would be nice to *warn* on self-calls (or perhaps other uses of `this`) before all finals are DA. For primitives classes we can outlaw such things, of course. Basically, for both primitive and identity class constructors, it is a likely bug if you use `this` (for something other than initializing `this`) before all final fields are DA. And yet some constructors perform additional operations (such as sanity checks) in an object constructor, when the object is in DA and “almost finished” state. It would be smart, I think, to make the rules in this area, as coherent as possible, for both kinds of classes. IIRC the status quo is that no uses of `this` are legitimate in a constructor body except field writes (of DU fields) and field reads (of DA fields). I think that is too strict, compared to the laxness of the rules for identity classes, and given the usefulness of error checking methods being called from constructors.