F# has two kinds of data types – “classes” and “types”. Types are bags of bits, similar to C structs, only immutable (that’s C, without sharp). Classes are classes in a normal object-oriented sense.
F# types cannot be null
. Values that may or may not be present are expressed via special type 'a option
. So, int option
means optional integer, conceptually very similar to Nullable<int>
. int option
can take values None
or Some(x)
.
In Ocaml classes are also not nullable. F# needed to be compatible with .NET libraries, so it introduced null
keyword, but only for classes. F# classes are both nullable and optionable.
Note, that null
is not the same as None
, and Nullable<int>
and int option
are different data types.
Confused? I bet you are. And I have one more thing up my sleeve: .NET structs. This is a nut that F# authors did not crack yet.
F# types are .NET structs are both not-nullable, but they are not the same thing. F# types can’t have methods, .NET structs can. F# types don’t derive from object
, .NET structs do. Et cetera, et cetera.
Also, while Nullable<T>
is conceptually similar to T option
, these are two different, incompatible things.
The bottom line is, checking something for null
in F# is very not obvious.
Permalink
To summarize, F# has structs, classes, primitive, record and variant types and only handle null classes.
You say “In Ocaml classes are also not nullable” but many OCaml data structures (see the splay tree and finger tree implementations, for example) use the unsafe Obj.magic() to work around this deficiency in OCaml. That is a poor man’s null and, consequently, your OCaml library accidentally corrupts the OCaml run-time and causes segmentation faults to occur randomly at any time afterwards, undermining the stability of your all applications that use it. ExtLib has been known to do this, for example. In contrast, the equivalent code in F# is not only completely safe (and vastly more heavily tested because .NET has so many more users than OCaml) but is often much faster because options do not necessarily incur boxing as they do in OCaml.
You also imply that F# does not support structs but that is not true. F# not only supports structs but its own complex number implementation is entirely based upon structs and is many times faster than OCaml’s as a consequence. Indeed, OCaml has no support whatsoever for unboxed user types. This is another one of the practically-important deficiencies of OCaml that has been fixed in F# (thanks to .NET).
Finally, your bottom line “checking something for null in F# is very not obvious” is silly. Check for null in F# just as you do in C# otherwise don’t.
Permalink
I do not compare F# and OCaml. It could very well be that F# is better and/or faster than OCaml. Whatever the situation, there is a duality between Nullable and T option – they both do essentially the same thing, but they are not compatible.
At the time of writing of the post “structs” were marked TBD in F# language spec. But they issued a new spec a couple of days ago, so I may want to revisit.
By “checking of null being not easy” I meant that you need to know what kind of thing you are dealing with and write either .IsNone or == null, or nothing at all, since it cannot be null. Once you know the nullness behavior of your object, writing the check is indeed trivial
Permalink
Nullable is only intended for value types whereas the ‘a option type is completely generic.
Permalink