|
|
|
|
|
by marxama
3563 days ago
|
|
I've mentioned this before, but it's worth mentioning again: unfortunately, F# is not guaranteed to be null-less. As soon as you are working with instances of some class (for example string), you are back to normal null checking. Of course you can wrap the string in an option, but it can still have a value which is null... So even if you don't have any kind of interop, you can still end up with NREs. So what you'll have to do is tell your teammates to not use nulls, and instead make proper use of option etc, and then you're back to avoiding NREs by conventions, not by the compiler helping you out. Am I incorrect in this? F# seems like a very nice language, but honestly, C# is getting so much love from Microsoft that I haven't felt motivated to learn F# properly (the situation is very different in Java land). Seems like non-nullable references may even make it into C#, so there you go! :) |
|
You're not wrong, but I think you're being too rigid. Type safety isn't a yes or no, it's a sliding scale between mathematically-guaranteed correctness at compile time and unsafe user convention, and on that scale F# is definitely to the left of C# - although it's to the right of Haskell and dependently-typed langs - because while it doesn't provide full safety, it still make safe code easier to write (the famous "pit of success").
Sure, F# lets you write "null" instead of "None" if you want. But C# lets you write, e.g., "dynamic" - does that mean C# lacks static typing and "avoids MissingMemberExceptions by convention"? Of course not; you have to go out of your way to use dynamic, because the language provides you with static types and encourages you to use them. Likewise, F# provides you with the Option type and encourages you to use it - you have to go out of your way to use null in its stead.
A F# coworker that used null would be committing an obvious code review faux pas, much like a C# coworker that insisted on using dynamic duck typing instead of interfaces.
(Whereas "null" is generally not considered a code smell in C#... and note that it's entirely possible and not at all difficult to implement a safe Option type in C#! It's just neither idiomatic nor popular.)
Another example is casting. In weaker languages, casting is implicit and dangerously uncontrollable. C# does better: you must explicitly cast types, but it's up to you to make sure it's a safe cast. And F# goes a tiny bit further: you have separate operators for safe upcasts and unsafe downcasts, and using the former on an unsafe cast won't compile. It's not 100% safety, but it's still better.