Hacker News new | ask | show | jobs
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! :)

1 comments

> 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?

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.

I agree with you, and yes, F# does help you write safer code. My main objection is with people claiming that NREs cannot happen in F#, which is simply incorrect - it sure happened to me when I was learning some F# and tried some interop (and you're not going out of your way in doing interop, using some external library or what have you). Which is fine I guess, but I think it's important to be clear about the benefits of the language when recommending it.