Now that the C# 6 is finally going to have this long-anticipated ?. operator, is there similar thing in F#? And I'm not talking about ? operator.
-
4You could register a proposal at http://fslang.uservoice.com/forums/245727-f-language - As mentioned in my comments below, I'd be downvoting it rather than upvoting it if I could though :) – Ruben Bartelink Jun 06 '14 at 08:57
-
So from I read so far, I'm concluding that the answer to my question is "No". I wanted simple "Yes" or "No". Please write it as a proper answer so I can accept it. – Endrju Jun 06 '14 at 09:00
-
2I support @MarkSeemann's answer 100%; he's said 1) the answer is No (yes he hasnt said it explicitly) 2) here's why 3) this is what you do instead. I call that an Acceptable Answer all day long. But there is *slight* room for debate about programming language design (though despite using F# for a significant amount of time I wouldn't necessarily feel qualified to call something a plain ommission - the what to leave out aspect is a key component of language design and one of *the* reasons to choose a language). If that is to occur, the uservoice is a far better forum than here. – Ruben Bartelink Jun 06 '14 at 09:03
-
4It's a bit like asking *Why do I have to type `mutable` all the time* ? When is F# going to support auto-`mutable` like C# has for ages - I have lots of code that would be shorter with it... – Ruben Bartelink Jun 06 '14 at 09:07
-
Come on... I'm not asking "why". I'm asking a closed question where proper answer is "yes" or "no"... – Endrju Jun 06 '14 at 09:09
-
Yes, you've pinpointed the exact problem with your line of 'debate'. Please don't be offended when people say [mu](http://en.wikipedia.org/wiki/Mu_(negative)#.22Unasking.22_the_question) – Ruben Bartelink Jun 06 '14 at 09:11
-
Ruben I'm not offended :) It's just that without precise context of my use case it's not possible to tell if this operator would be legitimate or not. Yet everyone assume that the code is erroneous, broken, badly designed and so on. Come on, don't read between the lines :) – Endrju Jun 06 '14 at 09:15
-
1http://kolektiv.github.io/fsharp/aether/2014/08/13/aether-guide/ – Ruben Bartelink Aug 31 '14 at 01:49
-
1@Ruben cool! After few minutes I already like Aether. Make it the answer, and I'll accept it. – Endrju Aug 31 '14 at 09:09
3 Answers
Idiomatic F# doesn't have null values at all, so what use would it be? In F#, the most common way to model the absence of a value is to use option
.
When I need to interoperate with .NET code that may return null
, I convert it to an option as soon as possible, using a function like this:
let toOption (x : obj) =
match x with
| null -> None
| _ -> Some x
As soon as you have your value modelled as an option
, you can compose it with e.g. Option.map, and that serves the same purpose (but better, and safer) than the proposed C# operator.

- 225,310
- 48
- 427
- 736
-
This is what I'm talking about. If I have a .NET SomeObject.SomeComponent.SomeSubcomponent.Property and any of it can be null? – Endrju Jun 06 '14 at 08:40
-
3Then you have have a horribly designed system that you should hide behind an *Anti-Corruption Layer* (see [DDD](http://amzn.to/WBCwx7)). – Mark Seemann Jun 06 '14 at 08:42
-
Mark, the question is not about design choices, or usage patterns (which I might not be able to change for legitimate reasons), but about the presence or absence of the conditional access operator in the F# language to support shorter, easier to read, and less bug prone code. – Endrju Jun 06 '14 at 08:46
-
2@Endrju And if any of these fields is null, you want to just do nothing, like `?.` does? How often is that really what you want? Most of the time you'll want to process the case where `SomeObject` is null, the case where `SomeComponent` is null and the case `SomeSubComponent` is null differently, which is easy to do with pattern matching on `None` but forces you to go back to bug-prone `if (a.b.c == null)`s in C#. `?.` is just not flexible enough to warrant a dedicated language construct IMO. – Tarmil Jun 06 '14 at 08:48
-
@Tarmil no! Most of the cases are exactly the opposite. I just want to access the property, and if it's not available for a reason that something along the way is null, I want to take `0` for example. And your last sentence is wrong, as we can see in C# 6... – Endrju Jun 06 '14 at 08:50
-
4@Endrju The sort of sprinking of 'just in case' code and the thinking it engenders leads to extremely messy and hard to maintain code in my experience. You're not listening to Mark's core point: Nulls are not part of the F# way and you should be using some form of ACL which takes nulls, just in case check sprinkling, *and `NullReferenceExceptions`* out of the equation before you write your real code – Ruben Bartelink Jun 06 '14 at 09:01
-
4@Endrju In case it wasn't already obvious from my answer, the short answer to your question is: *no*, F# doesn't have such an operator. As other people have pointed out, you can propose such a feature, or perhaps even contribute it, but I doubt it'd be accepted... At least, I don't think it fits into Functional thinking. That C# 6 is now getting this feature doesn't change that. In fact, I opposed this particular C# feature when it was first presented for MVP review, because it leads to harder-to-maintain code, but I was rather alone in my criticism... – Mark Seemann Jun 06 '14 at 10:39
-
Mark, I tend to agree with you, that from pure functional perspective it's not needed. However interoperability with other .NET code designed in OO way, sometimes adhering to xDD, sometimes just written in dirty way to quickly solve small problems, and the near-infinite number of possible scenarios, makes room for things like this operator. You may be disgusted to use it, however it may be practical for others. And F# is not purely functional language, it's just functional-first. Thank you for your answer and the comments. – Endrju Jun 06 '14 at 10:50
-
1@Endrju FWIW, I wasn't trying to be snarky with my Anti-Corruption Layer comment, although I realize that it might be interpreted like that (if so, please accept my apologies). Lots of code is like that, and is totally outside of your control (external libraries, etc.). The best way to deal with such code is to hide it behind a function which'll return the appropriate value (e.g. None) if any of the properties in the [Train Wreck](http://en.wikipedia.org/wiki/Law_of_Demeter) are null... Now that I think about it, perhaps you *could* generalize this with Code Quotations... – Mark Seemann Jun 06 '14 at 10:50
-
1Mark yes, you're right all the way. But sometimes in really simple cases I'd just want zero default without additional thinking `mycollection?.FirstOrDefault(filter)?.Subcomponent?.Property ?? 0`. I don't know if filter would yield any result. Or if collection contains any data. Maybe not. Nowadays I do the same but I write many additional lines to check for null along the way, which lead to more boilerplate code, lot of noise, and still leaves room for NullReferenceExceptions. (Substitute "I" for at least 5000 votes for this feature in C#/VB). – Endrju Jun 06 '14 at 10:59
-
I'd like to see something like this in the F# API. I suggested an Option.ofNull. http://fslang.uservoice.com/forums/245727-f-language/suggestions/6103054-add-option-ofnull-to-help-remove-nulls – Cameron Taggart Jun 26 '14 at 18:20
-
@MarkSeemann I'm curious why (x:obj) and not let it be generic? I'm learning F# so I realize the answer might be obvious to anyone with any experience. – Luis Ferrao Jan 20 '19 at 09:14
-
1@LuisFerrao IIRC, the function that I proposed in my answer (from 2014) is now in F# as `Option.ofObj`. Why not let `x` be generic? Have you tried writing the function yourself? What happened? – Mark Seemann Jan 20 '19 at 09:27
-
@MarkSeemann I did, but since I just started with F# I'm not sure it's right. I ended up writing something that mimics Option.map so that I can call it like `naughtyInteropNullable |> map (fun x -> y)`, see the code here: https://dotnetfiddle.net/i9836j – Luis Ferrao Jan 20 '19 at 11:47
-
@LuisFerrao Ah, you use the `null` constraint. FWIW, I wasn't aware of that. Two alternatives that explains the above code, then: 1. I was just ignorant of the `null` constraint when I wrote the answer. 2. It's a later language feature. I actually don't know which one it is. FWIW, it looks like the now-built-in `ofObj` function is [implemented in yet another way](https://github.com/fsharp/fsharp/blob/98b0b1813268c37477d4c62c303f5700f2c247e9/src/fsharp/FSharp.Core/option.fs#L89). – Mark Seemann Jan 20 '19 at 12:13
-
Thanks for pointing out ofObj, that should be the new answer to this question I suppose – Luis Ferrao Jan 20 '19 at 13:11
You can lift your nullable into option first. And then you can use an option computation expression to achieve the same thing.

- 3,828
- 2
- 19
- 28
-
+1 Do you have a better link than these two? http://en.wikibooks.org/wiki/F_Sharp_Programming/Computation_Expressions http://fsharpforfunandprofit.com/posts/computation-expressions-intro/ – Ruben Bartelink Jun 06 '14 at 09:47
In functional languages, conditional / compositional traversal, especial in nested structures is generally modelled using the notion of lenses which is explained with a succinct example in this SO thread.
In the F# environment, there's Aether; see intro article and guide, which builds on the Lenses support developed and written about by Mauricio Scheffer in FSharpx here.

- 1
- 1

- 59,778
- 26
- 187
- 249