Kotlin Help

What's new in Kotlin 1.7.20-Beta

Release date: 1 August 2022

The Kotlin 1.7.20-Beta release is out! Here are some highlights from this preview version of Kotlin:

Support for Kotlin K2 compiler plugins

The Kotlin team continues to stabilize the K2 compiler. K2 is still in Alpha (as announced in the Kotlin 1.7.0 release), but now it supports several compiler plugins. You can follow this YouTrack issue to get updates from the Kotlin team on the new compiler.

Starting with this preview version, the Kotlin K2 compiler supports the following plugins:

The Alpha version of the new K2 compiler only works with JVM projects. It doesn't support Kotlin/JS, Kotlin/Native, or other multi-platform projects.

To enable the Kotlin K2 compiler and test it, use the following compiler option:

-Xuse-k2

Learn more about the new compiler and its benefits in the following videos:

Leave your feedback on the new K2 compiler

We really appreciate your feedback in any form:

Preview of the ..< operator for creating open-ended ranges

This beta release introduces the new ..< operator. Kotlin has the .. operator to express a range of values. The new ..< operator acts like the until function, and helps you define the open-ended range.

Our research shows that this new operator does a better job at expressing open-ended ranges and making it clear that the upper bound is not included.

Here is an example of using the ..< operator in a when expression:

when (value) { in 0.0..<0.25 -> // first quarter in 0.25..<0.5 -> // second quarter in 0.5..<0.75 -> // third quarter in 0.75..1.0 -> // last quarter <- note closed range here }

Standard library API changes

The following new types and operations will be introduced in the kotlin.ranges packages in the common Kotlin standard library:

New OpenEndRange interface

The new interface to represent open-ended ranges is very similar to the existing ClosedRange<T> interface:

interface OpenEndRange<T : Comparable<T>> { // lower bound val start: T // upper bound, not included in the range val endExclusive: T operator fun contains(value: T): Boolean = value >= start && value < endExclusive fun isEmpty(): Boolean = start >= endExclusive }

Implementing OpenEndRange in the existing iterable ranges

Currently, in a situation when a user needs to get a range with excluded upper bound, they use until function producing a closed iterable range effectively with the same values. In order to make these ranges acceptable in the new API that takes OpenEndRange<T>, we want to implement that interface in the existing iterable ranges: IntRange,LongRange, CharRange, UIntRange, ULongRange. So they will be implementing both ClosedRange<T> and OpenEndRange<T> interfaces simultaneously.

class IntRange : IntProgression(...), ClosedRange<Int>, OpenEndRange<Int> { override val start: Int override val endInclusive: Int override val endExclusive: Int }

rangeUntil operators for the standard types

rangeUntil operators will be provided for the same types and their combinations that currently have rangeTo operator defined. For the purposes of prototype, we provide them as extension functions, but for consistency we plan to make them members later, before stabilizing the open-ended ranges API.

How to enable the ..< operator

In order to use the ..< operator or to implement that operator convention for your own types, you should enable the -XXLanguage:+RangeUntilOperatorcompiler option.

The new API elements introduced to support the open-ended ranges of the standard types require an opt-in, as usual for an experimental stdlib API: @OptIn(ExperimentalStdlibApi::class). Alternatively, you could use a compiler option: -opt-in=kotlin.ExperimentalStdlibApi.

Read more about the new operator in this KEEP document.

The new Kotlin/Native memory manager is enabled by default

Kotlin 1.7.20 comes with the new Kotlin/Native memory manager enabled by default. This release brings further stability and performance improvements, allowing us to promote the new memory manager to Beta.

The previous memory manager made writing concurrent and asynchronous code complicated, including issues with implementing the kotlinx.coroutines library. This blocked the adoption of Kotlin Multiplatform Mobile because concurrency limitations created problems with sharing Kotlin code between iOS and Android platforms. The new memory manager finally paves the way to promote Kotlin Multiplatform Mobile to Beta.

The new memory manager also supports the compiler cache that makes compilation times comparable to previous releases. For more on the benefits of the new memory manager, see our original blog post for the preview version. You can find more technical details in the migration instructions on GitHub.

Configuration and setup

Starting with Kotlin 1.7.20, the new memory manager is the default. Not much additional setup is required.

If you've already turned it on manually, you can remove the kotlin.native.binary.memoryModel=experimental option from your gradle.properties or binaryOptions["memoryModel"] = "experimental" from the build.gradle(.kts) file.

If it's necessary, you can switch back to the legacy memory manager with the kotlin.native.binary.memoryModel=strict option in your gradle.properties. However, compiler cache support is not available for the legacy memory manager anymore, so compilation times might become worse.

Freezing

In the new memory manager, freezing is deprecated. Don't use it unless you need your code to work with the legacy manager (where freezing is still required). This may be helpful for library authors that need to maintain support for the legacy memory manager or developers who want to have a fallback if they encounter issues with the new memory manager.

In such cases, you can temporarily support code for both new and legacy memory managers. To ignore deprecation warnings, do one of the following:

  • Annotate usages of the deprecated API with @OptIn(FreezingIsDeprecated::class).

  • Apply languageSettings.optIn("kotlin.native.FreezingIsDeprecated") to all the Kotlin source sets in Gradle.

  • Pass the compiler flag -opt-in=kotlin.native.FreezingIsDeprecated.

Calling Kotlin suspending functions from Swift/Objective-C

The new memory manager still has a restriction on calling Kotlin suspend functions from Swift and Objective-C from threads other than the main one, but you can lift it with a new Gradle option.

This restriction was originally introduced in the legacy memory manager due to cases where the code dispatched a continuation to be resumed on the original thread. If this thread didn't have a supported event loop, the task would never run, and the coroutine would never be resumed.

In certain cases, this restriction is no longer required, but a check of all the necessary conditions can't be easily implemented. Because of this, we decided to keep it in the new memory manager, while introducing an option for you to disable it. For this, add the following option to your gradle.properties:

kotlin.native.binary.objcExportSuspendFunctionLaunchThreadRestriction=none

The Kotlin team is very grateful to Ahmed El-Helw for implementing this option.

Leave your feedback

This is a significant change to our ecosystem. We would appreciate your feedback to help make it even better.

Try the new memory manager on your projects and share feedback in our issue tracker, YouTrack.

Generic inline classes

Kotlin 1.7.20-Beta allows the underlying type of JVM inline classes to be a type parameter. The compiler maps it to Any? or, generally, to the upper bound of the type parameter.

Consider the following example:

@JvmInline value class IC<T>(val a: T) fun foo(s: IC<String>) {} // compiler generates fun foo-<hash>(s: Any?)

The function accepts the inline class as a parameter. The parameter is mapped to the upper bound and not to the type argument.

To enable this feature, use the -language-version 1.8 compiler option.

How to update to the Kotlin 1.7.20-Beta

Install Kotlin 1.7.20-Beta in any of the following ways:

  • If you use the Early Access Preview update channel, the IDE will suggest automatically updating to 1.7.20-Beta as soon as it becomes available.

  • If you use the Stable update channel, you can change the channel to Early Access Preview at any time by selecting Tools | Kotlin | Configure Kotlin Plugin Updates in your IDE. You'll then be able to install the latest preview release. Check out these instructions for details.

Once you've installed 1.7.20-Beta, don't forget to change the Kotlin version to 1.7.20-Beta in your build scripts.

Last modified: 08 August 2022