Nullity (was: User model stacking: current status)
Brian Goetz
brian.goetz at oracle.com
Thu May 12 12:22:06 UTC 2022
> Here is my current concept of this beast:
>
The next installment of this is: how does assignment and conversion
work? Presumably, it starts with:
- there is a null-discarding conversion from T? to T! (this is a
narrowing conversion)
- there is a nullability-injecting conversion from T! to T? (this is a
widening conversion)
and then we get to decide: which conversions are allowed in assignment
context? Clearly a nullability-injecting conversion is OK here
(assigning String! to String? is clearly OK, it's a widening), so the
question is: how do you go from `T?` to `T!` ? Options include:
- it's like unboxing, let the assignment through, perhaps with a
warning, and NPE if it fails
- require a narrowing cast
> Enter Valhalla:
>
> * (Let's say we have B1, B2a/B3a (atomic), and B2b/B3b ("b"reakable?))
> * On a B3 value type like `int`, `?` would be nonsense and `!` redundant.
> * That's equally true of a B3 value type spelled `Complex.val` (if
> such a thing exists).
> * (assuming `Complex` is ref-default) all three of `Complex`,
> `Complex?`, and `Complex!` have valid and distinct meanings.
If we have both .val and nullity annotations I think we are losing. The
idea here would be that B3.val *is literally spelled* `B3!`. The
declaration story is unchanged: class B1 / value-based class B2 / [
non-atomic ] value class B3, for some suitable spellings.
> Now, imagining that we reached this point... would B3a/B3b (as a
> language-level thing) become immediately vestigial?.
Unfortunately not. We need permission to unleash the zero-default type,
because many B2 types (e.g., LocalDate) have no good zero. So B3 is
needed to unlock that.
> With Complex as a B2a or B2b, would `Complex!` ever not optimize to
> the B3-like *implementation*? I think the (standard) primitives could
> be understood as B2 themselves, with `int` just being an alias for
> `Integer!`.
A B3:
value class Integer { ... } // int is alias for Integer!
What this short discussion has revealed is that there really are two
interpretations of non-null here:
- In the traditional cardinality-based interpretation, T! means: "a
reference, but it definitely holds an instance of T, so you better have
initialized it properly"
- In the B3 interpretation, it means: "the zero (uninitialized,
not-run-through-the-ctor) value is a valid value, so you don't need to
have initialized it."
> Con: To the extent full emotional types do not align clearly with
> primitive type projections, we might be painted into a corner and
> it might be harder to do emotional types.
>
>
> I'm questioning whether we would need primitive type projections at
> all, just nullable/non-null type projections.
Indeed, that was the point of my query.
More information about the valhalla-spec-observers
mailing list