

Null-checking considerations in F# – it's harder than you think - latkin
http://latkin.org/blog/2015/05/18/null-checking-considerations-in-f-its-harder-than-you-think/

======
MichaelGG
It sounds like this boils down to a codegen problem/bug with == / <>, mm? I
recall a similar problem doing comparisons on some value types, perhaps it was
DateTime (IIRC, this was before VS2010). The fix was to add another case to
the operator to make it take the fast path (do a direct call to the compare
method vs some crazy generic path). Rather than make the code more verbose to
hack around compiler limitations, fix the compiler? Though:

    
    
      if x == null then ... else ...
    

is about the same as:

    
    
      match x with null -> ... | _ -> ...
    

That said, null checking was never a perf area nor anything I've really had to
deal much with in years of working with F#.

~~~
latkin
The "crazy generic path" is still the default, but in F# 4.0 now there is a
module `NonStructuralComparison` which can be opened, shadowing all of the
generic operators with fast non-generic guys. See
[this]([http://blogs.msdn.com/b/dotnet/archive/2015/04/29/rounding-o...](http://blogs.msdn.com/b/dotnet/archive/2015/04/29/rounding-
out-visual-f-4-0-in-vs-2015-rc.aspx)) blog, search for "non-structural
comparison operators".

~~~
MichaelGG
When I get to a PC I'll try it out. But basically instead of using IComparable
directly (so you'd just have a single function call), it used to do something
far more complicated first, but still end up calling the same compare
function.

For equality I'd expect it to inline a check for null before calling the full
equality check. Then a later optimization pass or the JIT could fix it up to
be just the null check.

------
kyllo
Is there some .NET platform / interop issue that requires F# to have null
references? SML and OCaml have Option types and Haskell has the Maybe Monad.
It seems weird that F#, being an ML-family language, requires checking for
references to null.

~~~
kvb
Idiomatic F# code also uses Option types. However, all .NET reference types
have null as a possible value. While most F# types don't have null as a
"normal" value, there's nothing to prevent null instances of these types from
being created "abnormally" at the .NET runtime layer (e.g. values of F# types
created in other .NET languages like C# that don't respect F#'s metadata
annotations, or created via F# operators like Unchecked.defaultof<_> that
implicitly use the .NET runtime's default value of null for reference types).

In practice this is rarely a problem, but the article is highlighting what you
need to do when you want to (efficiently) check for these boundary cases.

------
DanielBMarkham
This is really good stuff, but most importantly remember that every time you
go out to .NET and could get a null, sort it all out as close to the call as
possible. Don't be cute and wrap it in an option, or try some 3-levels-out
try-catch block from hell. Acknowledge what could happen and deal with it.

I've found that every little bit my code gets away from that call without
handling the null, things get more and more complicated.

~~~
wtetzner
> Don't be cute and wrap it in an option

Unless of course that's the right semantics. Often methods use nullable
references as a poor man's Option.

