Value types and nulls (original) (raw)
Stephen Colebourne scolebourne at joda.org
Fri May 18 21:04:57 UTC 2018
- Previous message (by thread): hg: valhalla/valhalla: instanceof and Class.isInstance() fixes
- Next message (by thread): Value types and nulls
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Going out on a limb here, I'd like to say that nulls are useful, and value types need to have a similar concept.
Why? Because null is both a pain and useful. It is widely used to represent an absence of something, and that concept applies just as much to value types as reference types. For example, int has the nullable java.lang.Integer as a companion that can be used when you need a nullable int. Note that I'm no great lover of null - within our codebase a null never crosses a compilation unit boundary. But we still need the concept of nullable int (and nullable LocalDate).
Does it have to be null? Why not Optional? Or a typed null? Or a box? Well maybe - I'm trying to keep on open mind on the exact way to represent "absence", but I'll call it null for the rest of this email.
Thus, I think that is absolutely necessary to support however it is spelled. What I really don't want is that the nullable version is punished by having the same negative performance/space cliff edge of int vs Integer. That would be hugely undesirable.
On 15 May 2018 at 23:53, John Rose <john.r.rose at oracle.com> wrote:
One way to look at it is that you are proposing two new kinds of concrete classes to go with our old object class.
- object class = what we have today: identity-rich, nullable, not flattened - value class = new, flattened*, not nullable, identity-free - enforced value-based class = new, nullable, not flattened, identity-free
This looks pretty appealing as a starting point to me and worth exploring. The key downside is the lack of flattening, which has the negative performance/space trade-off I object to.
As discussed before though, the likelihood is that many value types will have a spare bit pattern that could be used to mean null - LocalDate and Currency certainly do for example. Whereas other value types will not have a spare bit pattern Long128. Can this not be embraced? Can we also say that its not just migration that needs this
- its more generally useful?
Value type category A:
- All bits significant, no spare bit pattern (eg. Long128), all-zero bit pattern must have logical meaning
- Use site choice of non-null or nullable (non-null gets the better syntax)
- When the variable is use-site declared as non-null, the JVM flattens as per the original plan. Arrays fully flattened.
- When the variable is use-site declared as nullable, the JVM still flattens, but with one additional bit (probably padded to 32/64). I suspect this effectively amounts to "subclass" of the value type with an extended memory layout. Arrays of the nullable form use this extended memory layout. While this isn't as flat it would be if it was non-null, its still much better than being an array of references with memory pointer hops.
- Long128 would use 128 bits per variable or array entry when declared non-null, but might use 160 bits when nullable.
Value type category B:
- A spare bit pattern is available to use as null (eg. LocalDate)
- The JVM has "normal" NPEs when making method/field calls if the bit pattern is all zeroes (null)
- Flattening happens, its just that the all-zero bit pattern actually means null.
- Variables are always nullable. Arrays are therefore always nullable.
- Just like there is no way to express use-site nullability for references, its not essential to express use-site nullability for category B
Existing published classes should only be migrated to category B. This allows the JVM to be much tougher when it finds mixed compilation issues with category A (just throw Error).
Effectively, this gives developers the choice between:
- values that work much like existing classes ("code like a class, but go faster")
- values that work much like primitives ("code like a class, works like an int with a null-like friend").
This seems like a desirable choice for the long-term, not just a migration hack.
thanks Stephen
- Previous message (by thread): hg: valhalla/valhalla: instanceof and Class.isInstance() fixes
- Next message (by thread): Value types and nulls
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]