Kotlin
A concise multiplatform language developed by JetBrains
Kotlin 1.6.0 Released
Kotlin 1.6.0 is now officially released with Stable exhaustive whens
, Kover, and a new memory manager for Kotlin/Native. Other language and standard library features released in 1.5.30 became Stable as well. Thanks for the feedback you’ve shared with us. If you still haven’t tried these new features out, now is the time!
In this blog post, you can find an overview of the following updates:
- Language features with sealed when statements, suspending functions and suspend conversions, instantiation of annotation classes, improved regular type inference and builder type inference.
- Kotlin/JVM with optimized delegated properties and repeatable annotations.
- Kotlin/Native with a preview of a new memory model, Xcode 13 support, a cross-compilation of Windows targets, LLVM and linker updates, performance updates, and unified compiler plugin ABI.
- Option to disable downloading of Node.js and Yarn for Kotlin/JS.
- Kover announcement.
- Standard library with new functions for standard input, Stable
typeOf()
, Stable Duration API, and other stabilized stdlib functions.
Subscribe to our blog and don’t miss out on any Kotlin updates
How to update
If you use IntelliJ IDEA or Android Studio, you have the option to automatically update to the new Kotlin release as soon as it becomes available.
Learn more about installing Kotlin 1.6.0.
Language features
We stabilized features from Kotlin 1.5.30 based on your feedback.
Sealed (exhaustive) when
statements
Sealed when
is a long-awaited feature that makes the Kotlin compiler warn you if your when statements are not exhaustive. This makes your code safer without having to introduce your own functions.
Kotlin has always been exhaustive in checking when
expressions for sealed classes, enums, and Boolean types. It is useful when you model your domain with those algebraic data types. For example, you might have different contact preferences for users of your app modeled as a sealed class hierarchy:
Now, if you write an expression that returns a different result based on different contact preferences, the compiler will flag an error if you forget to handle all of the types you have in your app:
This is a great help, both in writing code and for future maintenance. If you add a different type of contact preference later, you know that the compiler will make sure you have not forgotten to handle the different types of contact preferences all around your code.
However, before Kotlin 1.6, the following code that uses when
statements successfully compiles, even though it totally forgets to handle sending an announcement to your users via instant message:
Only a weak IDE inspection was reported, without any messages from the compiler. Starting from Kotlin 1.6, it produces the following compiler warning:
Non-exhaustive 'when' statements on sealed class/interface will be prohibited in 1.7. Add an 'is InstantMessage' branch or 'else' branch instead.
In Kotlin 1.7 it will become an error, leaving no chance to accidentally forget it. Please see KT-47709 for a more detailed explanation of the change and its effects.
Suspending functions as supertypes
Kotlin 1.6 stabilizes support for implementing suspend
functional types as super interfaces. It was one of the missing pieces in the Kotlin coroutines design.
When you design Kotlin APIs, it is idiomatic to accept functional types when you need to customize the behavior of various library functions. For example, kotlinx.coroutines
API has a member function in its Job interface that looks similar to this:
You can conveniently use this function with lambdas like invokeOnCompletion { doSomething() }
. If you have a class that you wanted to handle the completion with, you can streamline and optimize your code by implementing the functional type () -> Unit
directly in your class without creating an additional lambda:
Starting from Kotlin 1.6 this optimization is possible with suspending functions. If your APIs accept suspending functional types, like this:
… then you are not limited to passing lambdas and suspending function references to this code anymore. You can implement the corresponding suspending functional types in a class, too:
Suspend conversions
Kotlin 1.6 stabilizes conversions from regular to suspending functional types. You can now pass any expression of a suitable regular functional type where suspending is expected as a parameter. The compiler will perform a conversion automatically.
This fixes a small but annoying inconsistency in the interaction between regular and suspending functions in Kotlin. In you have a higher-order function that accepts a suspending function, like a collect call on a Kotlin Flow, then instead of using a lambda to call it, like this:
… you might find it convenient to pass a reference to the processItem
function to the collect
call to the same effect:
You would then extract a reference to your processing function into a variable in order to customize the behavior in your code. However, that didn’t work in Kotlin versions prior to 1.6. This is because you have a regular function that is being passed as a parameter of a suspending type:
In Kotlin 1.6, the above code compiles and works, too.
Improved type inference for recursive generic types
From 1.6.0, the Kotlin compiler can infer a type argument based only on the upper bounds of the corresponding type parameter if it is a recursive generic by default. This makes it possible to create various patterns with recursive generic types that are often used in Java to make builder APIs.
Builder inference improvements
Kotlin 1.5.30 introduced the -Xunrestricted-builder-inference
compiler option, which made type information about a builder call available to get inside builder lambdas. Namely, it introduced the ability of making calls that return an instance of a not yet inferred type, such as get()
inside a buildList()
lambda.
Starting with 1.6.0, you don’t need to specify -Xunrestricted-builder-inference
to make previously prohibited calls. With the -Xenable-builder-inference
compiler option, you can now also write your own generic builders without applying the @BuilderInference
annotation and automatically enable builder inference if regular type inference cannot resolve type information.
Supporting previous API versions for a longer period
Starting with Kotlin 1.6.0, you can now develop using three previous API versions instead of two (along with the current stable one). Currently, this includes API versions 1.3, 1.4, 1.5, and 1.6.
Kotlin/JVM
Repeatable annotations with runtime retention. Kotlin, like Java 8, has repeatable annotations. With Kotlin 1.6, the feature is compatible with Java, and @kotlin.annotation.Repeatable
now accepts any retention and makes the annotation repeatable both in Kotlin and Java. Java repeatable annotations are now also supported from the Kotlin side.
Kotlin/Native
Now you can try the Experimental version of the new Kotlin/Native memory manager. With this feature we are moving closer to providing a consistent developer experience in multiplatform projects. This means that the new memory manager lifts the existing restrictions on object sharing between threads and provides fully leak-free concurrent programming primitives that are safe and don’t require any special management or annotations from the developers.
You can freely update your Xcode and continue working on your Kotlin projects, as Kotlin/Native now supports Xcode 13.
Compilation of Windows targets on any host. You can compile Windows targets mingwX64
and mingwX86
on any host that supports Kotlin/Native.
We’ve reworked the LLVM dependency that Kotlin/Native uses under the hood. This brings some benefits along with an updated LLVM version to 11.1.0 and decreased dependency size.
Unified compiler plugin ABI with JVM and JS IR backends. Now, the Kotlin Multiplatform Gradle plugin is able to use the embeddable compiler jar – the one used for JVM and JS IR backends – for Kotlin/Native. You can now use the same compiler plugin artifacts for Native and other supported platforms.
Kotlin/JS
For building on a server without internet connectivity, you can now disable downloading Node.js and Yarn for Kotlin/JS projects and use the instances already installed on the host.
Kover
Since the first release, precise measurement of code coverage has been a challenge. Some great tools like JaCoCo work with Kotlin code, but they are not fully integrated with our Gradle toolchain and multiplatform projects. In this Kotlin release, we have started to fix this issue. Meet Kover, our new Gradle plugin that measures code coverage for Kotlin code built with the Kotlin/JVM compiler. Now it is in the early development stage and is experimental – we would appreciate your feedback on it in GitHub.
Watch the Kover video for more details.
Standard library
Kotlin 1.6.0 completes three stdlib roadmap items by getting rid of !!
after readLine()
, stabilizing typeOf()
, and providing a Stable Duration API. It also promotes the following stdlib functions to Stable:
- Collection builders
- Bit rotation operations on integers
- Regex function for splitting a string into a sequence
We’ve also added the ability to call compareTo
in infix notation and invested in providing a consistent experience with replace()
functions on JVM and JS.
New functions for standard input
In Kotlin 1.6.0, we got rid of the need to use the not-null assertion operator !!
after reading a line from the standard input in order to improve the experience for newcomers and simplify teaching Kotlin.
We provide new functions for reading from the console with the following experience:
readln()
throws an exception when EOF has been reached. Use this function instead of checking the result ofreadLine()
fornull
with the!!
operator.- The new
readlnOrNull()
is anull
-returning alternative. It behaves in the same way as the formerreadLine()
but has a more representative name.
These functions are now available for JVM and Native. The naming convention for these functions is now consistent with the println()
counterpart, which is especially important for newcomers.
Stable Duration API
Thanks to your feedback, we have stabilized the Duration API and closed the corresponding roadmap item.
In addition to a more readable output of Duration.toString()
and new functions for parsing Duration from String that were available for preview in 1.5.30, the Duration API has received the following changes:
- The
days
component of thetoComponents
function now has theLong
type instead ofInt
to avoid cutting off values. - The
DurationUnit
enum is now not a type alias. There are no cases of using it as a type alias for java.util.concurrent.TimeUnit
on JVM. - In response to community feedback, we’re bringing back extension properties like
Int.seconds
. To limit their applicability, they are available only in the Companion of the Duration class.
Stable typeOf()
Kotlin 1.6.0 brings Stable typeOf()
and closes the corresponding roadmap item. Since 1.3.40, typeOf()
has been available on the JVM platform as an experimental API, and now you can use it on any Kotlin platform and get a KType
representation of any Kotlin type that the compiler can infer.
Stable collection builders
Kotlin 1.6.0 promotes collection builder functions – buildMap()
, buildList()
, and buildSet()
– to Stable. Collections returned by the builders are now serializable in their read-only state.
Stable bit rotation operations for integers
In Kotlin 1.6.0, the rotateLeft()
and rotateRight()
functions, which rotate the binary representation of the number left or right by the specified number of bits, became Stable.
Stable Regex function for splitting a string into a sequence
Kotlin 1.6.0 also stabilizes splitToSequence()
– a function for regular expressions that splits a string into a sequence.
compareTo in infix notation
We’ve added the ability to call the Comparable.compareTo
function in infix notation to compare two objects for order:
Consistent replace() and replaceFirst() on JVM and JS
Before Kotlin 1.6.0, the replace()
and replaceFirst()
Regex functions behaved differently on JVM and JS when the replacement string contained a group reference. The behavior on Kotlin/JS is now consistent with that on JVM.
Compatibility
As with all feature releases, some deprecation cycles of previously announced changes are coming to an end with Kotlin 1.6.0. All of these cases were carefully reviewed by the language committee and are listed in the Compatibility Guide for Kotlin 1.6. You can also explore these changes on YouTrack.
How to install Kotlin 1.6.0
If you’re using IntelliJ IDEA or Android Studio, your IDE will suggest updating Kotlin to 1.6.0 automatically. Alternatively, you can update manually by following these instructions.
You can download the latest versions of these IDEs to get extensive support for Kotlin:
- IntelliJ IDEA – for developing Kotlin applications for various platforms.
- Android Studio – for developing Android and cross-platform mobile applications.
Make sure that you have also updated the kotlinx libraries to the compatible versions and specified Kotlin 1.6.0 in the build scripts of your existing projects.
If you need the command-line compiler, download it from the Github release page.
If you run into any problems:
- Find help on Slack (get an invite).
- Report issues to our issue tracker, YouTrack.
Stay up to date with the latest Kotlin features! Subscribe to receive Kotlin updates by filling out the form to the right of this post.
What else to read and watch
- Kotlin roadmap
- Kover – The Code Coverage Plugin
- What’s new in Kotlin 1.6.0 in the documentation
- What’s new in Kotlin 1.6.0 on YouTube
- Compatibility guide for Kotlin 1.6
- Kotlin 1.5.30 Is Now Available!
Top issue reporters from YouTrack
Ryan Nett (48 issues), Zac Sweers (22 issues), Tianyu Geng (18 issues), zhelenskiy (18 issues), Thodoris Sotiropoulos (15 issues), AndroidDeveloperLB (14 issues), Morgan, Bartholomew (14 issues), Mikhail Naftal (14 issues), Louis CAD (12 issues), Philip Wedemann (12 issues), Victor Turansky (11 issues), Igor Wojda (11 issues), Martin Bonnin (11 issues), Iaroslav Postovalov (11 issues), Cedric (10 issues), 凛 (9 issues), Ben Woodworth (8 issues), Tianyi Guan (8 issues), Chris Povirk (8 issues), Alon Albert (8 issues).
External contributors
We’d like to thank all of our contributors whose pull requests were included in this release: Pyos, Tianyu Geng, Jinseong Jeon, Steven Schäfer, Mark Punzalan, Hung Nguyen, Mads Ager, Ting-Yuan Huang, Matthew Gharrity, Ivan Gavrilovic, Xin Wang, ov7a, Jiaxiang Chen, Yigit Boyar, Bingran, bracadabra, Steffi Stumpos, Andrey Kuleshov.