Hacker News new | past | comments | ask | show | jobs | submit login

The first is a union type, and the second is a disjoint union type. The second is also known by the names of tagged unions, sum types, and discriminated unions.

For the first to be useful, there needs to be some hidden disjoint union to implement it (how else would you know it's an int vs the adjoined null?) but the type equivalence rules would let unions collapse: union(T,Null,Null) = union(T,Null).

Here's an illuminating example I saw once: consider a class with a member that represents a value that is known or unknown, and it might take some time to initialize the value. There are three states: uninitialized, initialized but unknown, and initialized and known. This can be modeled by nullable(nullable(T)). If the nullable collapses, you can't tell the difference between uninitialized and unknown anymore.




I like having a semantic difference for async values (maybe not computed yet) and for optional values (maybe no value).

Thus you get Future<Optional<T>>. It is of course helpful since the "Do this when a value happens, do that when a failure happens" algorithms can be encoded onto the future. Obviously you don't want people implementing busy waits.

Edit: as to your overall point, I agree that this just cannot be modeled with null. The intention is just not capturable.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: