What's New in Kotlin 1.1

Table of Contents

JavaScript

Starting with Kotlin 1.1, the JavaScript target is no longer considered experimental. All language features are supported,
and there are many new tools for integration with the front-end development environment. See below for
a more detailed list of changes.

Coroutines (experimental)

The key new feature in Kotlin 1.1 is coroutines, bringing the support of async/await, yield and similar programming
patterns. The key feature of Kotlin's design is that the implementation of coroutine execution is part of the libraries,
not the language, so you aren't bound to any specific programming paradigm or concurrency library.

A coroutine is effectively a light-weight thread that can be suspended and resumed later. Coroutines are supported through suspending functions: a call to such a function can potentially suspend a coroutine, and to start a new coroutine we usually use an anonymous suspending functions (i.e. suspending lambdas).

Let's look at async/await which is implemented in an external library, kotlinx.coroutines:

Here, async { ... } starts a coroutine and, when we use await(), the execution of the coroutine is suspended while the operation being awaited is executed, and is resumed (possibly on a different thread) when the operation being awaited completes.

The standard library uses coroutines to support lazily generated sequences with yield and yieldAll functions.
In such a sequence, the block of code that returns sequence elements is suspended after each element has been retrieved,
and resumed when the next element is requested. Here's an example:

Note that coroutines are currently considered an experimental feature, meaning that the Kotlin team is not committing
to supporting the backwards compatibility of this feature after the final 1.1 release.

Other Language Features

Type aliases

A type alias allows you to define an alternative name for an existing type.
This is most useful for generic types such as collections, as well as for function types.
Here is an example:

Sealed and data classes

Kotlin 1.1 removes some of the restrictions on sealed and data classes that were present in Kotlin 1.0.
Now you can define subclasses of a top-level sealed class on the top level in the same file, and not just as nested classes of the sealed class.
Data classes can now extend other classes.
This can be used to define a hierarchy of expression classes nicely and cleanly:

Interception of delegated property binding

For delegated properties, it is now possible to intercept delegate to property binding using the
provideDelegate operator.
For example, if we want to check the property name before binding, we can write something like this:

Scope control for implicit receivers in DSLs

In Kotlin 1.0, code in the lambda passed to td has access to three implicit receivers: the one passed to table, to tr
and to td. This allows you to call methods that make no sense in the context - for example to call tr inside td and thus
to put a <tr> tag in a <td>.

In Kotlin 1.1, you can restrict that, so that only methods defined on the implicit receiver of td
will be available inside the lambda passed to td. You do that by defining your annotation marked with the @DslMarker meta-annotation
and applying it to the base class of the tag classes.

rem operator

The mod operator is now deprecated, and rem is used instead. See this issue for motivation.

Standard library

String to number conversions

There is a bunch of new extensions on the String class to convert it to a number without throwing an exception on invalid number:
String.toIntOrNull(): Int?, String.toDoubleOrNull(): Double? etc.

val port = System.getenv("PORT")?.toIntOrNull() ?: 80

Also integer conversion functions, like Int.toString(), String.toInt(), String.toIntOrNull(),
each got an overload with radix parameter, which allows to specify the base of conversion (2 to 36).

onEach()

onEach is a small, but useful extension function for collections and sequences, which allows to perform some action,
possibly with side-effects, on each element of the collection/sequence in a chain of operations.
On iterables it behaves like forEach but also returns the iterable instance further. And on sequences it returns a
wrapping sequence, which applies the given action lazily as the elements are being iterated.

also(), takeIf() and takeUnless()

These are three general-purpose extension functions applicable to any receiver.

also is like apply: it takes the receiver, does some action on it, and returns that receiver.
The difference is that in the block inside apply the receiver is available as this,
while in the block inside also it's available as it (and you can give it another name if you want).
This comes handy when you do not want to shadow this from the outer scope:

takeIf is like filter for a single value. It checks whether the receiver meets the predicate, and
returns the receiver, if it does or null if it doesn't.
Combined with an elvis-operator and early returns it allows to write constructs like:

takeUnless is the same as takeIf, but it takes the inverted predicate. It returns the receiver when it doesn't meet the predicate and null otherwise. So one of the examples above could be rewritten with takeUnless as following:

Map.toMap() and Map.toMutableMap()

Map.minus(key)

The operator plus provides a way to add key-value pair(s) to a read-only map producing a new map, however there was not a simple way to do the opposite: to remove a key from the map you have to resort to less straightforward ways to like Map.filter() or Map.filterKeys().
Now the operator minus fills this gap. There are 4 overloads available: for removing a single key, a collection of keys, a sequence of keys and an array of keys.

minOf() and maxOf()

These functions can be used to find the lowest and greatest of two or three given values, where values are primitive numbers or Comparable objects. There is also an overload of each function that take an additional Comparator instance, if you want to compare objects that are not comparable themselves.

Map.getValue()

This extension on Map returns an existing value corresponding to the given key or throws an exception, mentioning which key was not found.
If the map was produced with withDefault, this function will return the default value instead of throwing an exception.

Abstract collections

These abstract classes can be used as base classes when implementing Kotlin collection classes.
For implementing read-only collections there are AbstractCollection, AbstractList, AbstractSet and AbstractMap,
and for mutable collections there are AbstractMutableCollection, AbstractMutableList, AbstractMutableSet and AbstractMutableMap.
On JVM these abstract mutable collections inherit most of their functionality from JDK's abstract collections.

Array manipulation functions

The standard library now provides a set of functions for element-by-element operations on arrays: comparison
(contentEquals and contentDeepEquals), hash code calculation (contentHashCode and contentDeepHashCode),
and conversion to a string (contentToString and contentDeepToString). They're supported both for the JVM
(where they act as aliases for the corresponding functions in java.util.Arrays) and for JS (where the implementation
is provided in the Kotlin standard library).

JVM Backend

Java 8 bytecode support

Kotlin has now the option of generating Java 8 bytecode (-jvm-target 1.8 command line option or the corresponding options
in Ant/Maven/Gradle). For now this doesn't change the semantics of the bytecode (in particular, default methods in interfaces
and lambdas are generated exactly as in Kotlin 1.0), but we plan to make further use of this later.

Java 8 standard library support

There are now separate versions of the standard library supporting the new JDK APIs added in Java 7 and 8.
If you need access to the new APIs, use kotlin-stdlib-jre7 and kotlin-stdlib-jre8 maven artifacts instead of the standard kotlin-stdlib.
These artifacts are tiny extensions on top of kotlin-stdlib and they bring it to your project as a transitive dependency.

Parameter names in the bytecode

Kotlin now supports storing parameter names in the bytecode. This can be enabled using the -java-parameters command line option.

Constant inlining

The compiler now inlines values of const val properties into the locations where they are used.

Mutable closure variables

The box classes used for capturing mutable closure variables in lambdas no longer have volatile fields. This change improves
performance, but can lead to new race conditions in some rare usage scenarios. If you're affected by this, you need to provide
your own synchronization for accessing the variables.

javax.script support

Kotlin now integrates with the javax.script API (JSR-223).
The API allows to evaluate snippets of code at runtime:

kotlin.reflect.full

To prepare for Java 9 support, the extension functions and properties in the kotlin-reflect.jar library have been moved
to the package kotlin.reflect.full. The names in the old package (kotlin.reflect) are deprecated and will be removed in
Kotlin 1.2. Note that the core reflection interfaces (such as KClass) are part of the Kotlin standard library,
not kotlin-reflect, and are not affected by the move.

JavaScript Backend

Unified standard library

A much larger part of the Kotlin standard library can now be used from code compiled to JavaScript.
In particular, key classes such as collections (ArrayList, HashMap etc.), exceptions (IllegalArgumentException etc.) and a few
others (StringBuilder, Comparator) are now defined under the kotlin package. On the JVM, the names are type
aliases for the corresponding JDK classes, and on the JS, the classes are implemented in the Kotlin standard library.

Better code generation

The external modifier

If you need to access a class implemented in JavaScript from Kotlin in a typesafe way, you can write a Kotlin
declaration using the external modifier. (In Kotlin 1.0, the @native annotation was used instead.)
Unlike the JVM target, the JS one permits to use external modifier with classes and properties.
For example, here's how you can declare the DOM Node class:

Improved import handling

You can now describe declarations which should be imported from JavaScript modules more precisely.
If you add the @JsModule("<module-name>") annotation on an external declaration it will be properly imported
to a module system (either CommonJS or AMD) during the compilation. For example, with CommonJS the declaration will be
imported via require(...) function.
Additionally, if you want to import a declaration either as a module or as a global JavaScript object,
you can use the @JsNonModule annotation.