michaelbull / kotlin-result

A multiplatform Result monad for modelling success or failure operations.
ISC License
1.05k stars 63 forks source link

Rename Result to Either #73

Closed 1gravity closed 2 years ago

1gravity commented 2 years ago

This is a great library and I'm using it for back- and frontend Kotlin code likewise! One issue I have with it is that the IDE usually picks kotlin.Result as a default for the import and I have to manually add the com.github.michaelbull.result.Result import. Using Either would be closer to the standard for what Result represents (not just closer, exactly spot on ;-). Thanks for considering.

michaelbull commented 2 years ago

One issue I have with it is that the IDE usually picks kotlin.Result as a default for the import

You can configure IntelliJ to exclude kotlin.Result from auto-importing, as shown here.

Using Either would be closer to the standard for what Result represents (not just closer, exactly spot on ;-)

I disagree. Result is very strict in its definition, it specifically represents a success/failure of an operation, with the success on the left and the failure on the right. Either not an accurate representation whatsoever of this, it's more generic and is actually misleading.

With an Either type you are trying to add an "OR" to the type system, to say it's returning a String OR an Int for example, but this isn't really what you end up with as the Either<String, Int>. An Either type is not commutative or symmetric, i.e. Either<Int, String> does not equal Either<String, Int>. This also then introduces the problem of choosing a "biased side" for what you consider the success or the error (whether it's left or right), which varies across different functional languages.

Rich Hickey (author of Closure) has a very in-depth explanation of why Either is a misnomer.

If you truly wish to use Either, you can import com.github.michaelbull.result.Result as Either

1gravity commented 2 years ago

Thanks for the explanations, you convinced me.

michaelbull commented 2 years ago

You're very welcome - thanks for the feedback on your usage of the library, it's great to hear. I've been around the Either/Result loop a few times, I think the true best way to solve it is on a type level with union types that languages like TypeScript have, e.g. myFunction(): String | Int which returns a String or an Int within the type system without resorting to monads.

1gravity commented 2 years ago

I agree, I'm looking forward to having union types in Kotlin as well. So do a lot of other developers, #1 feature requested: https://blog.jetbrains.com/kotlin/2021/12/kotlin-features-survey-2021-results/.

kolyneh commented 1 year ago

Hi @michaelbull, I have configured IntelliJ to exclude kotlin.Result from auto-importing, but it's not working. 😂 I think it's better if we change Result to an interface, then add a typealias definition for it:

...
- public sealed class Result<out V, out E> {
+ public sealed interface Result<out V, out E> {
...

+ // IResult for example because it is an interface, other names would be ok.
+ typealias IResult<K, V> = Result<K, V>  

And then we can use IResult to avoid conflict with kotlin.Result.

michaelbull commented 1 year ago

@kolyneh The docs[1] don't seem to suggest that the base Result would need to be an interface instead of a sealed class. You should be able to just declare typealias IResult<K, V> = com.github.michaelbull.result.Result in your project and work around the problem you're hitting with IntelliJ. I can't say I'm hitting the same problem though, I've excluded it and it never suggests the stdlib one.

[1] https://kotlinlang.org/docs/type-aliases.html

kolyneh commented 1 year ago

@michaelbull Yah, there is no need to use a sealed interface instead. Just an example to add an alias for Result. Thanks!