Closed laynepenney closed 7 years ago
Without these changes, it is currently legal to have a nullable option value:
Could you explain what's wrong with having Option
for nullable types?
@ilya-g 'cause Option
represent the presence of absence of a value. Allowing nulls for Option
s defeat the whole purpose.
Do you have any specific use case for an Option
of nullable type?
null
is a valid value for a nullable type and is not an absence of value.
As for the use cases, consider collection of unconstrained type T
. Before I could write an extension, say Collection<T>.findOption(predicate): Option<T>
which would have returned Some(T)
when it found an item and None
when it didn't.
Another use case is Map<K, V>.getOption(K): Option<V>
which again could return Some(V)
even if the key is mapped to null
value.
Now I either have to constrain the receivers to have non-nullable type arguments, or I can't distinguish missing value from null
. Then what is the purpose of Option
? Why should I use it instead of plain nullable types?
Indeed both cases were valid before this PR
But we did have a map.option[x]
that returns Some<T>
or None
toOption()
doesn't make sense if is already not null...
And I, indeed, had this biting my ass a few days ago with a map, that I ended replacing with :?
https://github.com/MarioAriasC/funKTionale/blob/master/src/main/kotlin/org/funktionale/memoization/namespace.kt#L288
Interesting... let me think about it
A decision should be made before hitting 1.0
@ilya-g your first case is already implemented (Collection<T>.findOption(predicate): Option<T>
)
and toOption()
is still possible
If it uses firstOrNull
it still doesn't allow to distinguish between null and missing value.
I've always used "null" as None in kotlin.
Functional languages do not have anything like null, they just have None.
@ilya-g In which real-world use-cases do you need both null and None?
@d3xter The actual question is, shall we allow nullable types inside Option
?
By having an Option<String?>
technically is possible to have a Some(null)
weird, but is explicit and the Kotlin compiler will provide all the null safe guards.
Right now isn't possible as we don't allow nullable types...
I'd say no. As said above, None is usually used as Value does not exist or Value is not set
When having Some(null), what does null stand for? It must not be Value does not exist Does it mean "Not Available"? "Not yet loaded"? I'd rather get an Enum-constant called Unknown or an empty class with a name, because then it is clear what it means.
And it can also lead to confusion for People, who come from functional languages, because they expect to get Some with a value in it.
This is a non exhaustive list of pros and cons of both approaches
Option<T: Any>
aka Strict Not-Nullabe Option (Current implementation)Pros | Counter argument | Counter-counter argument |
---|---|---|
Some doesn't allow null (expected behaviour) |
The same could be achieved with the other softer option type | N/A |
Strict default | N/A | N/A |
Cons | Counter argument | Counter-counter argument |
---|---|---|
Limited functionality when interacts with types other than T: Any (e.g Writing extension functions) |
N/A | N/A |
T: Any is uncommon on Kotlin codebases, making Option<T: Any> unidiomatic |
N/A | N/A |
Option<T>
aka Soft Option (previous implementation, considering coming back)Pros | Counter argument | Counter-counter argument |
---|---|---|
Flexible | Allows null |
It must be explicitly declared (Option<String?> ) and all Kotlin's null-safety features apply |
Idiomatic (covariance, extension functions and so on) | N/A | N/A |
Other implementations are similar (@kmizu [https://github.com/kmizu/kollection]) | N/A | N/A |
Cons | Counter argument | Counter-counter argument |
---|---|---|
Allows null |
It must be explicitly declared (Option<String?> ) and all Kotlin's null-safety features apply |
N/A |
Right now I'm seriously thinking on coming back to Option<T>
Your thoughts?
+1 for Optionnull
does not necessarily mean absent
, so it makes sense to me that we shouldn't be trying to reinvent a language feature in this sense, and opt for the more open, flexible approach.
The type system will automatically enforce non-nullability. It would be up to the programmer to decide to allow nulls in the optional.
Description
Better handle Option and Either generics. The default upper bounds in Kotlin, if not specified, is Any? -> [https://kotlinlang.org/docs/reference/generics.html#upper-bounds (https://kotlinlang.org/docs/reference/generics.html#upper-bounds).
Without these changes, it is currently legal to have a nullable option value:
Examples