Published: May 30, 2024
24
72
424

The Lead Kotlin Designer announced the biggest change to Kotlin in years: union types with errors. That might significantly change how we deal with exceptional cases and how we use Kotlin. Let me show you how it works and what support we can expect. Thread 🧵 👇

Image in tweet by Marcin Moskała

Union types are supertypes of both types, so String | Error is a supertype of both String and Error, so it accepts both String and Error. Just like Int? accepts both Int and null (Int? is like Int | null).

Image in tweet by Marcin Moskała

This feature should particularly help when a variable needs to represent either a value or a placeholder for a lack of value, like T | NotFound. It is useful when null cannot represent a lack of value.

Image in tweet by Marcin Moskała

Union types with errors are also a replacement for types like Either or Result, just like nullable types were a replacement for Optional.

Image in tweet by Marcin Moskała

What is the advantage of using union types with errors instead of Either or Result? As a built-in construct, it can be much more efficient and convenient.

Either or Result must be represented with an object, that stores a value. Union types do not need that, they allow raw value passing. That also means we do not need to pack values, we can just use them where needed.

Union types with errors also support a number of operators, similar to those supported for nullable types.

- !. call will call a function or a property only if value is not an error, so a!.b translates to if(a is Error) a else a.b

- !: provides a default value in case of an error, so a !: b translates to if(a is Error) b else a

- !! just throws the throwable error if this value is an error, or returns the other value otherwise. So a!! translates to if(a is Error) a.throw() else a

With such support, we will be able to conveniently transform values in functional style. Just like we do now with nullability, but errors additionally store information about what went wrong.

Image in tweet by Marcin Moskała

Union types will be introduced step-by-step, first inside Kotlin stdlib to optimize algorithms.

Image in tweet by Marcin Moskała

To make it clear: Only union types with errors were announced as planned, and new operators were not announced yet, only shown as a considered option. It might also take quite some time until those features are added to the language.

@marcinmoskala Does it destrucuture to a pair behind the scenes? val (databaseResult, databaseError) = functionCall() Really curious to how it'll work.

@funky_muse No, under the hood, it is most likely going to be just Any; that is either a value or an error.

@marcinmoskala Nice feature but what is the advantage compared to using sealed class like below :

Image in tweet by Marcin Moskała

@_sanders_9 1. You need to wrap values with objects, what is costly. 2. Union types might have dedicated operators for easier processing. This is the same as nullable type vs Optional.

@marcinmoskala Is it in Kotlin 2.0?

@j_a_o_v_c_t_r No, it will take a lot of time to see those operators. Union types with errors should be introduced soon but in a limited scope.

@marcinmoskala could just use arrow 🤷‍♂️

@SilasSchwarz I thought about showing Arrow too, but it is a lot like Result, but not inlined and with a different API.

@marcinmoskala when/where was this announced? trying to find references to it to see what Kotlin version will have this feature.

@rakeebbb For now, only union types with errors were announced in the presentation Kotlin Language Features in 2.0 and Beyond. Those operators were shown as an idea in Revamping and Extending Kotlin's Type System presentation.

@marcinmoskala This sounds great. Regarding the current usage of Object types, there is an alternative https://github.com/michaelbull... which uses inline value classes to reduce overhead

@marcinmoskala Seems like half-baked union given there's only two types that can form a union. If this goes ahead, real unions might never happen :(

@marcinmoskala Nice. We've discussed this regarding rise4s, an ArrowKt-like library for Scala, and later even added this feature (https://x.com/riccardo_cardin/... It's sufficient for non-generic business code, but some important limitations are highlighted here: https://x.com/vergauwen_simon/...

@marcinmoskala This is fascinating. I feel like I'm both for and against this particular language feature. I'm for it because it'd simplify error handling by a lot. And all of the other reasons you've mentioned in the thread convinced me as well...

@marcinmoskala I heard in kotlinconf, they probably won’t add this feature.

@marcinmoskala this would be soooooooooooooo awesome

@marcinmoskala we are so typescript

@marcinmoskala This new feature just blew my mind. I wonder how this affects @arrow_kt types such as Either 🤔

@marcinmoskala This would be a BIG change

@marcinmoskala Can we have union types for whatever we want, a la Ceylon, or do we need to wait for the next moment of realization?

Share this thread

Read on Twitter

View original thread

Navigate thread

1/35