mitch
10/12/2023, 12:48 PMOption<T>
was godsend is because it doesn't have the nested nullability problems. We don't have to think about it when we write code.Youssef Shoaib [MOD]
10/12/2023, 2:21 PMsimon.vergauwen
10/12/2023, 2:30 PMT | Null
for T?
it'll probably open a can of worms with all existing code, and probably requires a bunch of special changes to support the current ?:
syntax only for | Null
.
Also T | Null | Null <~> T | Null
, so does it really solve the nested nullability issue? Perhaps (T | Null) | Null
🤔 cc\\ @Alejandro Serrano.Mena
Did you ever get to test that branch against Jackson, or Project Reactor @mitch?Youssef Shoaib [MOD]
10/12/2023, 2:32 PMsimon.vergauwen
10/12/2023, 2:32 PMval res: Any? = EMPTY
in libraries now, and it's super uglyA?
as A | None
would solve some nullability issues when working with Java too though. Some libraries don't allow null
as a valueAlejandro Serrano.Mena
10/12/2023, 3:07 PMsimon.vergauwen
10/12/2023, 3:10 PMA | B
and B | A
.
> The more I look into this, the more I think that the problem is conflating nullable types with a potential missing element in the collection
It goes beyond that, it's bitten me in non-collection generic code as well. The problem is always using null
as an "error" signal in generic contexts.mitch
10/13/2023, 1:18 PMT | null | null == T | null
.
Boxing null into a value type Option<T> == (T | null)
is also going to suffer the same fate i'm afraid... it means we would have an unrepresentable type when T is nullable I.e. Option<T?> == (T | null | null) == (T | null)
In other words, option as value class will make the Option type unsound for T?
I.e. it breaks identity law for any nullable type...
By contrast, swift and current arrow option uses tagged union of Option<T> = Some(T) | None
which is well behaved for any T and T? E.g. Option<T?> = Some(T | null) | None
Observe how it nests elegantly as well Option<Option<T>> = Some(Some(T) | None) | None
which simplifies to Some(Some(T)) | Some(None) | None