Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is None represented as null?

CompilationRepresentationFlags.UseNullAsTrueValue can be used to

Permit the use of null as a representation for nullary discriminators in a discriminated union

Option.None is the most prominent example of this.

Why is this useful? How is a null check better than the traditional mechanism for checking union cases (the generated Tag property)?

It leads to perhaps unexpected behavior:

Some(1).ToString() //"Some(1)"
None.ToString()    //NullReferenceException

EDIT

I tested Jack's assertion that comparing to null instead of a static readonly field is faster.

[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
type T<'T> =
  | Z
  | X of 'T

let t = Z

Using ILSpy, I can see t compiles to null (as expected):

public static Test.T<a> t<a>()
{
    return null;
}

The test:

let mutable i = 0
for _ in 1 .. 10000000 do
  match t with
  | Z -> i <- i + 1
  | _ -> ()

The results:

Real: 00:00:00.036, CPU: 00:00:00.046, GC gen0: 0, gen1: 0, gen2: 0

If the CompilationRepresentation attribute is removed, t becomes a static readonly field:

public static Test.T<a> t<a>()
{
    return Test.T<a>.Z;
}

public static Test.T<T> Z
{
    [CompilationMapping(SourceConstructFlags.UnionCase, 0)]
    get
    {
        return Test.T<T>._unique_Z;
    }
}

internal static readonly Test.T<T> _unique_Z = new Test.T<T>._Z();

And the results are the same:

Real: 00:00:00.036, CPU: 00:00:00.031, GC gen0: 0, gen1: 0, gen2: 0

The pattern match is compiled as t == null in the former case and t is Z in the latter.

like image 291
Daniel Avatar asked Aug 14 '12 19:08

Daniel


People also ask

Is None the same as null?

Python uses the keyword None to define null objects and variables. While None does serve some of the same purposes as null in other languages, it's another beast entirely. As the null in Python, None is not defined to be 0 or any other value. In Python, None is an object and a first-class citizen!

Is None the same as null in Python?

Instead of null, there's None keyword used in Python. so there is no comparison between Python None vs null. In other programming languages null is often defined to be 0, but in Python used None to define null objects and variables. But None is not defined to be 0 or any other value.

Are null and NaN the same?

NaN : means 0/0 -- Stands for Not a Number NA : is generally interpreted as a missing, does not exist NULL : is for empty object.

What does != null mean?

NULL is not a value. It is literally the absence of a value. You can't "equal" NULL! The operator != does not mean "is not"; it means "is not equal to".


1 Answers

The F# compiler sometimes uses null as a representation for None because it's more efficient than actually creating an instance of FSharpOption<'T> and checking the Tag property.

Think about it -- if you have a normal F# type (like a record) that's not allowed to be null, then any pointer to an instance of that type (the pointer used internally by the CLR) will never be NULL. At the same time, if T is a type which can represent n states, then T option can represent n+1 states. So, using null as a representation for None simply takes advantage of that one extra state value which is available by the fact that F# types aren't allow to be null.

If you want to try turning this behavior off (for normal F# types), you can apply [<AllowNullLiteral(true)>] to them.

like image 100
Jack P. Avatar answered Sep 21 '22 12:09

Jack P.