I think saying something is not the same as something else, when evidently the difference can to reduced down to syntactic sugar is a bad way categorizing and differentiating types.
Why nullable types?
91–100 of 119 posts
Re: Why nullable types?
#92I sometimes wonder if the problem is that we don't have enough nulls. null is typically used as a flag value, but the meaning can be ambiguous: maybe it's the absence of a value, maybe an error occured, etc. Sometimes it has more than one meaning for the same type. Maybe types should be allowed to declare multiple nulls (effectively like an Enum in java) for different flag values. Operations on the different nulls wo…
Completely reasonable request, easy to implement along the lines of: public class Name { private Name(String name, int flag){...} public static Name asMissing(){new Name(null, -1);} public static Name asNotApplicable(){new Name(null, -2);} public static Name asNotAvailableYet(){new Name(null, -3);} public static Name asForbidden(){new Name(null, -4);} public static Name create(String name){new Name(name, 0)} public b…
public class Name {
private Name(String name){...}
flags {
MISSING, NOT_APPLICABLE, NOT_AVAILABLE_YET, FORBIDDEN
}
...
}
In particular, you shouldn't have to specify a constructor, since these are flag values that don't necessary have any state associated with them.Re: Why nullable types?
#93I agree that union-typed null was the best solution for Dart, but I think many of the article's criticisms of option types aren't good. > We can’t perform arithmetic on an Option any more than we could on a List . Why not? One sensible definition is Some(x) + Some(y) = Some(x + y) _ + _ = None() > In fact, with Dart, we’ve found that most existing code is already statically null safe This is a very good reason to use…
> Different people will assign different meanings to null, and it's a real headache when trying to write generic code. This is a legitimate concern, but my experience has been that it is a surprisingly rare problem in practice. We software engineers are trained to believe that any system that supports 1 of something is obligated to generalize and support N of them. But you'd be surprised how far just one sentinel val…
Re: Why nullable types?
#94I agree that union-typed null was the best solution for Dart, but I think many of the article's criticisms of option types aren't good. > We can’t perform arithmetic on an Option any more than we could on a List . Why not? One sensible definition is Some(x) + Some(y) = Some(x + y) _ + _ = None() > In fact, with Dart, we’ve found that most existing code is already statically null safe This is a very good reason to use…
I agree with all your other points but > > We can’t perform arithmetic on an Option any more than we could on a List . > Why not? One sensible definition is (...) It's not the only sensible definition. It would be equally sensible to implement it as: Some(x) + Some(y) => Some(x+y) Some(x) + None => Some(x) None + Some(y) => Some(y) None + None => None
It can be interesting to see what other languages do in this situation. For example, C# got nullable value types in version 2, and had to decide what to do with operators in a similar vein (including pre-existing overloaded operators in user code) - they called it "lifting":
https://docs.microsoft.com/en-us/dotnet/csharp/language-refe... https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...
You might notice that it almost, but not quite, has consistent semantics: null means "unknown", which is particularly obvious from Booleans: (true | null) is true, and (false & null) is false, but (true & null) and (false | null) are both null. However, comparison operators aren't consistent: you'd expect x == null to be null if it meant "unknown", but the language will always give you either true or false; and ditto for relative comparisons. This last one means that it's possible for (x == y), (x y) to all be false.
What's interesting is that, in practice, it's rare to see reliance on any of this behavior in idiomatic C# code - "null" is usually used as "missing", not as "unknown", so all this magic is, at best, irrelevant, and at worst, actively harmful (because it defers a logic error).
Re: Why nullable types?
#95I sometimes wonder if the problem is that we don't have enough nulls. null is typically used as a flag value, but the meaning can be ambiguous: maybe it's the absence of a value, maybe an error occured, etc. Sometimes it has more than one meaning for the same type. Maybe types should be allowed to declare multiple nulls (effectively like an Enum in java) for different flag values. Operations on the different nulls wo…
Re: Why nullable types?
#96I think saying that Option types are different from nullable types is not true. They differ at the semantic level, around how you can interact with them (one requires you to case on whether or not the value is there, the other requires you to do that with an if statement), but at the type level the describe the same construct. I think saying something is not the same as something else, when evidently the difference c…
Imagine (sorry for pseudocode):
type Option T = Some T | None
type Nullable T = T | null
The difference here is that Option "tags" each part of its union, which guarantees that the parts are disjoint. In Nullable, the parts of the union are disjoint only if T is not itself nullable. If T is S | null, Nullable T is S | null | null, which is just S | null (since null and null are not disjoint.Re: Why nullable types?
#97I guess a third option would be to use an "Option" but with much more syntactic sugar. So, rather than calling func(some(3)), you'd just call func(3) and the compiler would automatically wrap it up. Func would be declared this way: def func(int?) to indicate that it's an optional type. IMO you get the best of both world. And then, in many places in the code, you'd have to do "r?.foo()" if r is an Option type. It's di…
TypeScript and, AFAIK, Kotlin provide exactly that. The problem with that special syntax sugar is that then there's no monad to compose with. But it does feel nice for many use cases.
function foo(x: number | undefined);
or you can have: function foo(x?: number);
The type of x inside foo is the same in both cases, but the type of foo differs. The first version can only be called as foo(x) - where x is possibly undefined - but the second one can also be invoked as foo(), which then has the same meaning as foo(undefined).But this is mostly because they were trying to come up with a type system to capture existing JavaScript patterns. I doubt it'd look like that if it could be designed from scratch.
Re: Why nullable types?
#98Rich Hickey had a good talk about problems of representing a missing information in programs, and why union types allow you to incrementally make changes in your codebase without refactoring the whole thing at once.
Re: Why nullable types?
#99Earlier quoted context omitted.
Adding an `Option` type to an existing language doesnt really solve many problems unless you can also somehow remove it's existing support for `null. Java added `Optional` and while it makes interacting with newer API's clearer, there is nothing preventing you from passing a null Optional. I think if you are designing a language from scratch, you should avoid null, but nullable types are a good feature for existing l…
Language culture matters. Scala has both `Option` and `null`, but there's a strong culture of "`null` is only for Java interop", so you very rarely see a `null` in the wild from libraries, or wonder whether it'd be valid to pass it in.
https://dotty.epfl.ch/docs/reference/other-new-features/expl...
I think that the expectation is that idiomatic Scala code will mostly still use `Option`, while `null` will be used for interoperability with Java, JavaScript or Scala libraries that happen to use `null`.
In any case, I am very much looking forward to these additions.
Re: Why nullable types?
#100Earlier quoted context omitted.
Adding an `Option` type to an existing language doesnt really solve many problems unless you can also somehow remove it's existing support for `null. Java added `Optional` and while it makes interacting with newer API's clearer, there is nothing preventing you from passing a null Optional. I think if you are designing a language from scratch, you should avoid null, but nullable types are a good feature for existing l…
Language culture matters. Scala has both `Option` and `null`, but there's a strong culture of "`null` is only for Java interop", so you very rarely see a `null` in the wild from libraries, or wonder whether it'd be valid to pass it in.