6 ms·
Just replied to MichaelGG on the same subject [1]. I understand what you're getting at. I'm not particularly looking to create an algebraically perfect type.
by louthy 12y ago
Just replied to MichaelGG on the same subject [1]. I understand what you're getting at. I'm not particularly looking to create an algebraically perfect type. The explicit reason for this is to kill null as a possible output from a method, so that the consuming code only has Some or None to deal with. If you want to return null, don't use Option<T>.
[1] https://news.ycombinator.com/item?id=8634015 https://news.ycombinator.com/item?id=8634015
- MichaelGG 12y agoIt only has Some or None to deal with. Some<T> or None. Also, do you take it all the way? By the current logic, Some(Some(null)) should also return None.
- dragonwriter 12y agoIf Some(null)is None, then shouldn't Some(Some(null)) be Some(None)? But I'd agree that Some(null) should just be Some(null) and not magically become None. Now, there should be a a generic function something like NullableToOptional<T> that returns an Option<T> by mapping any non-null value v to Some(v) and null to None, but it shouldn't be the core behavior, because you should be able to wrap a nullable value in an option.
- louthy 12y agoThis whole thread is food for thought definitely. I'll open an issue on the github page to get some feedback. I think if Some(null) doesn't become None then it should throw an exception instead rather than wrap null. I'm explicitly trying to control the number of possible outcomes, passing null back shouldn't be valid at all imo. So perhaps the conversion logic should be: x = Some(x) null = None Some(x) = Some(x) None = None Some(null) = Exception Some(None) = Exception Some(Nullable null) = Exception Some(Nullable x) = Some(x)
- wtetzner 12y agoI don't see any reason not to have Some(None) = Some(None).
- louthy 12y agoI see your point, but what does it mean? It means returning an Option<Option<T>>. I think I'd rather lift the value out automatically: Some(Some(x)) -> Some(x) Some(None) -> Exception Thoughts?
- dragonwriter 12y ago> I see your point, but what does it mean? It means returning an Option<Option<T>>. I think I'd rather lift the value out automatically Lifting the value out automatically loses much of the value of having option types. A large part of the value of Option types is that they preserve information that gets lost when using Nullable types for a similar purpose because you can nest them -- that is, the fact that Option<Option<T>> is a thing you can use where Nullable<Nullable<T>> isn't is a big part of the point of using an option type. Extracting the value is done explicitly.
- louthy 12y agoCould you give a concrete example? I've personally never found myself wanting to preserve nested options. What additional information does it preserve? I could perhaps see the value if C# had decent pattern matching, I'm not currently convinced it would bring much benefit to the average C# app.
- dragonwriter 12y ago> I've personally never found myself wanting to preserve nested options. Sure, but you never need to just because you can -- the most common use of chaining calls that can produce Options in any language that supports them is mapping functions accepting the wrapped type over the Options, which both results in in one non-nested Option at the end of the chain and makes the fact that the input is coming from an Option transparent to each of the calls in the chain. If you don't need the information preservation of nested Options (and its true that its less common that you do, and often Either is a better choice than Option for preserving information), then you just don't bother to explicitly wrap an Option in another Option. Magically special casing it so that wrapping an Option in an Option flattens it to a single, unnested Option doesn't seem to me like it serves much purpose but ruling out a use case that Option types enable over nullable types, because there's no reason you'd ever explicitly wrap an Option in an Option unless you wanted them nested -- and it makes the implementation more complicated to impose that unnecessary limitation.