4 ms·
A comment on the option type: I think transforming Some(null) into None is wrong. - There is an x for which Some(x) is not a Some. This violates useful invaria
by Strilanc 12y ago
A comment on the option type: I think transforming Some(null) into None is wrong.
- There is an x for which Some(x) is not a Some. This violates useful invariants.
- Some((int?)1) is a Some, but Some((object)(int?)1) is a None.
- optionValue.Cast<object>().Cast<T>() is not the identity function.
- I can't use your option type in existing code without doing careful null analysis.
- As a rule of thumb, generic code you should treat null as just another instance of T with no special treatment (beyond the acrobatics to make the code not throw an exception). That way both users enforcing a non-null constraint and users allowing nulls can use your type.
- louthy 12y agoJust 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.