https://kotlinlang.org logo
j

Jamie Taylor

05/28/2020, 3:10 PM
What's the general consensus on the best way to have a function that can fail in multiple different ways in Kotlin? I always thought we should use Result for that but just found out that it can't be the return type of a function. Should we just keep on throwing exceptions?
c

Chantry Cargill

05/28/2020, 3:10 PM
sealed classes are the way to go.
s

Stefan Beyer

05/28/2020, 3:11 PM
why cant it be in the return type?
c

Chantry Cargill

05/28/2020, 3:11 PM
It’s experimental ^
j

Jamie Taylor

05/28/2020, 3:12 PM
so do people normally make a sealed class for generic result types for each project they do, or make a separate sealed result type for each different type of result or what?
it seems like having a standard one that provides functions like map and flatmap would be useful
s

Sam Garfinkel

05/28/2020, 3:13 PM
Copy code
sealed class Result

data class Result1(): Result

data class Result2(): Result
etc.
c

Chantry Cargill

05/28/2020, 3:14 PM
That’s a matter of style. You can easily create a general Result type, but it’s also a fair pattern to have multiple types under a sealed class specific to your use case.
s

Sam Garfinkel

05/28/2020, 3:14 PM
Monads are a good solution here
s

Stefan Beyer

05/28/2020, 3:14 PM
When I just need this in very few places in a project, I usually use own sealed classes. But if it is a common theme, using libraries like Arrow would make sense 🙂
s

Sam Garfinkel

05/28/2020, 3:15 PM
With the sealed classes you can define two results, one that returns Exceptionally (fails) and one that Succeeds with a
val value: Any
Copy code
sealed class Result

data class ExceptionalResult(val exception: Throwable): Result

data class Success(val result: Any?): Result
c

Chantry Cargill

05/28/2020, 3:19 PM
j

Jamie Taylor

05/28/2020, 3:20 PM
Lots of sensible options, thanks
If you were starting a new project and needed a result type, is there any particular one you'd be more likely to go for?
c

Chantry Cargill

05/28/2020, 3:22 PM
I personally write my own, but as I say, it’s a matter of style.
s

Stefan Beyer

05/28/2020, 3:22 PM
and if you are writing a general solution yourself, dont use
Any
😄
Copy code
sealed class Result<T> {
    data class Success<T>(val value: T) : Result<T>()
    class ExpectedError<T>(val somethingThatHelpsToRecover: SomeType) : Result<T>()
    class UnexpectedError<T>(val errorMessage: String) : Result<T>()
    // ...
}
I also had some instances where I had several kinds of outcome, as well as several kinds of errors. at this stage, this whole thing becomes very funny ^^
☝️ 1
If you were starting a new project and needed a result type, is there any particular one you'd be more likely to go for?
my personal opinion is: • try to avoid writing generalized (generic) result types. (because they get ugly really quickly) • if you are not comfortable writing a sealed class for every case, then use a library like arrow. (10 sealed classes may be ok, 1000 is just ridiculous)
3 Views