Saturday, February 18, 2012

F# ≥ C# (Options)

Today is one of my most rewarding days. I’ve exchanged some ideas with Brian and Vlad on our team and get some good understanding of null value in F#.
Let us first tell me the discussion result. I am converted from an option hater to a lover, at least not that hate. The reason I hate option is the fact that I have to type “Some” every time and it is, to me, a redundant. I can use C# NULL to check if a variable is being set or not. Today I found out I was wrong, the option is a better way to handle this situation. It forces me to pay attention to check the value. Do you still remember the last time you encounter null exception? I guess not long time ago, right? Let us start with a C# sample with a string type variable.
string str = read_string(); //a function return a string type value
if (str.Length < 10) then Console.WriteLine(“less than 10”) else “long string… “
Seems everything is perfect until you realize the str can be null! L So you have to check str != null first and then perform the real work. If you forget at one place, a monster will be staring at you in the dark.
Let us look at the F# version:
let str = read_string()   // return a string option to indicate the return value can be an uninitialized value
match str with
| Some(data) -> printfn “good, we got value and we can process…”
| None -> printfn “what happened, call IT right now!”

We still need to write match and make decision about if the value is None or not, but at least this let you pay attention. Comparing to the C#'s implicit NULL approach, I start to like this way more. It is true that some people still prefer the C# version which puts the check everywhere, but if you write a SDK and expose it to end user, do you expect that guy’s code has a snickering monster? J
 Also the option avoid the reference type's NULL value, this NULL value is not a valid value in the problem space. For example, if we use the string to represent first name, what is NULL mean for a people's name? This implicit value give us tons of trouble and increase the complexity of the program because you have to check the NULL everywhere. Why not using an option and make your problem space clean?


Dmitry Lobanov said...

But you still has to check for None every time... isn't it the same as checking for null? What's the difference?

Just for the record. I love options and hate nulls... for me using options is more declarative and meaningful than using nulls.

Liu Tao said...

Yes, it is true we still need the match, but this force to pay attention to the fact that this value can have None, in C#'s case NULL. Comparing to C#'s implicit NULL, I think this way is better and lead to less bug.

Thorium said...


Null value is a very bad practice
as it breaks the
*Single responsibility principle*,
null has two responsibilites:

1) Be the unassigned state

2) Be the Special Case -pattern (Fowler PoEAA)

Option is just the Special Case.

We don't even need the unassigned state.