F# was supposed to free us of the tyranny of the unchecked null. Alas not only does it not do that, it introduces several more kinds of null. First consider this all too common problem in C# code.

int GetLength(string value) { return value.Length; }

Unless you have code analysis turned on and the function is publically available, you don’t get so much as a warning that this function may throw a NullReferenceException. Now let’s consider the F# equivalent.

let GetLength (value : string) = a.Length

Just like the C# version, this will throw a NullReferenceException if you accidentally pass a null to it. But unlike C#, you don’t even get so much as a warning.

Next up are nullable structures. Our test code in C# is followed by the F# equivalent.

static public bool IsPositive(int? value) { return value.Value > 0; }

let IsPositive( value : Nullable<int> ) = value.Value > 0

Again, both versions are susceptible to throwing exceptions. In this case an InvalidOperationException.

Now that we established that using traditional types are just as dangerous as every, we turn to the new option types. First we will recode GetLength using an “option ” instead of a normal string.

let GetLength2 (value : option<int> ) = value.Value.Length

Now we have the possibility for two different exceptions. If you pass “None” to the function you will get an InvalidOperationException. If you pass a “Some(null)” to the function, you will get a NullReferenceException. And again, there are no compiler warnings telling you that your code can fail.

F# also adds the concept of triple nulls. Since you can nest options inside options, you can write the downright silly functions such as:

let GetLength3 (value : option<string>) = value.Value.Value.Length

let IsPositive( value : option<int>) = value.Value.Value > 0

When using F# types instead of normal CLS types, things are somewhat better. Classes defined in F# cannot be assigned the value null. However, they can still be wrapped in an option type, throwing away the null-safety and bringing us back to the problem of no decent compiler warnings.