https://kotlinlang.org logo
Title
j

jdemeulenaere

06/26/2018, 1:29 PM
Is there any project out there to do explicit error handling in Kotlin ? I'm thinking of something similar to std::expected (as explained here: https://bell0bytes.eu/expected/). I've read a little bit about Try<T> in Arrow but IMO it's a little bit too much tied to functional programming and requires some knowledge of the Arrow library. I think that Kotlin could benefit from a small, simpler Try<T> class and one or two syntactic sugar allowed by a compiler plugin. I'm thinking for instance of unwrapping a Try<T> variable using the !! operator, or implicit conversion of any object of type T to Try<T> when returning a value.
See https://pastebin.com/DJVf1xS8 for a detailed example of what I have in mind.
g

gildor

06/27/2018, 12:48 AM
There is a plan for Result monad (actually almost the same as Try). If you need synthetic sugar from the language than it should be some proposal on Kotlin KEEP, or just write some draft and share to #language-proposals
My imo that for try monad you don't need simple unwrap syntax, because it will be overused and result will be the same as just throw exception from method but now with !! everywhere. Whole idea of Try is to easily propagate errors without unwrapping and have map/flatMap, yeah it's functional approach, but code that unwraps try using unsafe operator (or method) has smell and shouldn't be supported by language syntax
j

jdemeulenaere

06/27/2018, 7:24 AM
Thanks for you input! Maybe the choice of the !! operator for unwrapping is not the best, it was just a first idea. A syntactic sugar would just allow people to use Try cleanly in an imperative way, which has a lot of advantages compared to the functional approach (this is why suspending functions are so great, much easier to use and read code compared to Future/Deferred/Publisher/etc). There are few advantages over unchecked exceptions, for instance you explicitly have to handle the exception/propagate it, and you can easily share the Try value returned by a function in a thread with another thread, which makes writing libraries much easier (in that case they don't have to handle the special case where an exception occurred in user code). We use this exact kind of error handling internally at Google in C++ and it has been proved for many years to be the best way of managing errors. I will make a proposal when I find the time this week to have the opinion of the JetBrains team :)
g

gildor

06/27/2018, 7:53 AM
What is big difference between
try.getUnsafe()
and
try!!
?
also method can be much more flexible than !! or any other syntactic sugar:
try.getOrNull()
try.getOrDefault(someDefault)
try.getOrThrow(MyCustomException())
j

jdemeulenaere

06/27/2018, 7:55 AM
You could use try ?: defaultValue or try ?: throw MyCustomException() in those cases 🙂 Looks nice to me.
g

gildor

06/27/2018, 7:55 AM
what if try is nullable?
so it clashes with nullability, so you need full set of new operators
also what about
try?.value?.doSomething
? How this suppose to work if you want to consider Try as nullable
j

jdemeulenaere

06/27/2018, 7:57 AM
It doesn't clash, the operation would apply in the right order. If you have a Try<T>?, the first !! would return Try<T> or throw a NullPointerException. Then a second !! would unwrap T or make the function return a failure. If you have a Try<T?>, the order would be the other way around 🙂
If you have a Try<String>, you could do try?.length and you would get a Try<Int>
g

gildor

06/27/2018, 7:58 AM
I suppose before do proposal would be better to share your thoughts about language support and use cases in this task https://youtrack.jetbrains.com/issue/KT-18608
What if you have
Try<String?>?
j

jdemeulenaere

06/27/2018, 7:59 AM
try?.operationThatOnlyWorksOnTryString
g

gildor

06/27/2018, 8:00 AM
So nullableTry just unwrapped to non-nullable String?
j

jdemeulenaere

06/27/2018, 8:00 AM
in that case you could use try?.flatMap { it?.length } and you would get a Try<Int?>?
g

gildor

06/27/2018, 8:02 AM
At least syntax with functions doesn’t have this clash of operators. In case of
Try<String?>?
you have 3 different states: non-nullable String in Success nullable String in Success Failure And it’s easy to imagine cases when you want to distinguish all of them
j

jdemeulenaere

06/27/2018, 8:02 AM
But I would argue that this would never happen, methods should never return a nullable Try
g

gildor

06/27/2018, 8:02 AM
Why?
It’s kinda big restriction
And not very practical
j

jdemeulenaere

06/27/2018, 8:03 AM
How often do you encounters methods that return a nullable Future? 😉
It would be possible, just a really bad practice
g

gildor

06/27/2018, 8:03 AM
But try is not a future
Oh, sorry
j

jdemeulenaere

06/27/2018, 8:03 AM
I know, but the concept is the same. It's a monad
g

gildor

06/27/2018, 8:03 AM
In case of
Try<String?>?
you have 3 4 different states: non-nullable String in Success nullable String in Success Failure Null
So for more common case
Try<String?>
you have 3 states: non-nullable String in Success nullable String in Success Failure
I just worry about clash with nullability operators
it can be error prone
j

jdemeulenaere

06/27/2018, 8:05 AM
As I said, if the operator is a problem, we could use something different 🙂
But you do realize that the ?. operator has the same semantics as flatMap right?
and !! as unsafeGet
g

gildor

06/27/2018, 8:06 AM
In general I like your idea. I just think that it never be implemented because of many edge cases. If we talking about another operator
j

jdemeulenaere

06/27/2018, 8:06 AM
If the Kotlin team decides to introduce Monads one day I wouldn't be surprised that they use those operator as sugars
g

gildor

06/27/2018, 8:08 AM
But you do realize that the ?. operator has the same semantics as flatMap right?
Very similar, but you can nest monads (including Try), but you cannot nest nullable types
Just looks that Kotlin Team tries to implement new features as libraries using existing language features if it’s possible, rather than new syntax. But I see you point, it looks nice at first glance. Maybe make sense to propose it right now on KT-18608
It would be possible, just a really bad practice
Also agree with this, but you cannot prevent such usage. Because of this I’m asking how to handle those edge cases
Anyway, would be happy to see you comment on KT-18608 or KEEP
j

jdemeulenaere

06/27/2018, 8:18 AM
Thanks, I will do that later today when I'm back from work 🙂
👍 1
Done 🙂