Kotlin M14 is out!


With the release approaching, we switch to shorter milestones. Meet M14 that brings the following changes:

  • Support for annotations on file classes
  • New Java API for the Standard Library
  • operator modifier for operators
  • Backing fields are now accessed through a synthetic field variable

Language

We are wrapping up with the language changes, so nothing really dramatic has happened in M14.

NOTE: We are dropping previously deprecated features and functions, so make sure to have run Code Cleanup before you install M14.

Backing fields

The old $propertyName syntax is deprecated. To access backing fields inside getter/setter, use the field synthetic variable:

If another property in the same scope is named field, we need to qualify its usage with “this.“.

Var-properties with a backing field and a custom setter are required to be initialized upon declaration (not in the constructor), because such initializers are written to the backing field directly, bypassing the setter.

In the (probably rare) cases when this model is not flexible enough, please consider introducing backing properties (corresponding refactoring is available) or using property delegates.

Operators

As announced previously, Kotlin M14 expects functions that are called through operator notation (e.g. plus, iterator etc) to be marked with the operator modifier. Note: when we extend Any, Iterable or Comparable, operator modifiers are inherited automatically, so there’s no need to worry about them. When in need to use a Java method in the operator form, please use extension functions marked operator:

Use Code Cleanup to add modifiers to all the operators used in your project automatically.

Note: Infix functions will be migrated to the same scheme in the nearest future.

Compile-time constants

Since M14 we need to prefix Kotlin constants with const to be able to use them in annotations and see as fields from Java:

Code Cleanup will add missing const modifiers for you.

Annotate file classes

Since M13, top-level functions and properties from each source file are put into a separate class file by default (details here). Now we can annotate these classes by applying a file annotation:

will be compiled to

Migration from old “package facades”

As we have transitioned to the new class-file layout, it’s time to retire the old one. Since M14 old package-facade classes (e.g. FooPackage) are deprecated, and the IDE helps you migrate your Java code to the new scheme through Code Cleanup.

NOTE: package facades will be dropped very soon, so make sure to migrate your code.

The Standard Library (previously kotlin.KotlinPackage class) is being migrated to the new scheme too: see below.

Other language changes

  • private on the top level is now private to file
  • internal is checked in the compiler (not only IDE)
  • private in interfaces is truly private now
  • equals in data classes compares arrays by calling their .equals() method (which works by identity)
  • lateinit val‘s are prohibited
  • many cases of inheritance and other degrees of freedom are prohibited for data classed (see this blog post)
  • protected and internal members are prohibited in interfaces
  • _, __, ___ are forbidden as in identifiers, i.e. we can use _foo, but not _ alone (reserved for future use)
  • identityEquals() function is deprecated in favor of ===

Standard Library changes

For the Java standpoint, Kotlin’s standard library is now organized into utility classes, each dedicated to its own data types and/or operations. For example:

  • ArraysKt — operations on arrays, extensions for arrays, array factory methods
  • CharsKt — extensions for Char and Char.Companion, most of them should be hidden
  • CollectionsKt — operations on iterables, collections and lists, list factory methods
  • ComparisonsKt — operations on comparators, comparator factory methods, and functions for performing comparisons

See more in the API docs.

IDE Changes

As usual, the IDE helps you migrate seamlessly from M13 via Code cleanup. Also there are several new handy features in M14:

  • As mentioned above, there in some cases we need private backing properties. You can easily introduce them via intention action:

  • Also you can move property initialization from constructor body or initializer block to property declaration:

  • One of the long-expected features is completion for overriding functions and properties:

  • Since M13 the IDE optimizes imports on the fly. Add unambiguous imports on the fly feature is also supported now. Give it a try:

Installation

IntelliJ IDEA 15 Public Preview has Kotlin M14 bundled, so you don’t need to install it at all.

IntelliJ IDEA 14.1 — simply update your plugin as usual.

P.S. Join our Slack channels to discuss Kotlin and your experience with it!

About Andrey Breslav

Andrey is the lead language designer of Kotlin at JetBrains.
This entry was posted in Releases. Bookmark the permalink.

31 Responses to Kotlin M14 is out!

  1. Jayson Minard says:

    Congratulations to everyone involved in Kotlin, releases are accelerating!

  2. Are these features planned for Android Studio? My Android Studio always suggest me to turn off Kotlin plugin because it is incompatible :(, I’m in the canary channel.

    • Natalia Ukhorskaya says:

      Kotlin Plugin 0.14.449.Idea141.12 is compatible with Android Studio 1.4. What are your versions of Kotlin plugin and Android Studio?

  3. NN says:

    Will Kotlin support implicit returns ?
    Making everything expression body gives more readable code.

    There is no reason to abandon ‘return’ completely since quiting in the middle is a useful feature, but mostly you won’t need it.

    • Explicit returns have proven to be a very good readability aid. Also, see this discussion

      • NN says:

        The main issue is two forms of ‘if’ .
        One that is not an expression and the other is an expression.


        fun foo() {
        if (x) f();

        if (y) g() else z();
        }

        The solution is either have an explicit ‘return’ and use same name ‘if’ for both constructions, or introduce another keyword for ‘if’ statement.


        fun foo() {
        iff(x) print("not returning");

        // Last one returns value
        if (y) g() else z();
        }

        Since many people come from Java world and not Scala, it is not an obvious one.
        For this you can have an optional return . If you don’t specify it the last expression is returned.

        Thanks.

        • And two forms of when, and two forms of for (when it becomes an expression with yield introduced)? And we are keen on introducing control structure-like functions such as with, which would also require two forms each…

          • NN says:

            Not exactly :)
            loops are expressions returning Unit, there is no need for two forms.

            The only change is making ‘if’ with mandatory ‘else’. This ensures that ‘if’-‘else’ always return a value.

            And having a shortcut for ‘if(a) b else {}’ such as ‘ifs(a) b’ .

  4. NN says:

    What about delayed type inference ?


    var a; // a is Int according to the usage.
    ...
    if(true) a = 1; else a = 2;

  5. Daniel Rothmaler says:

    Wow… that was fast :-)

    But I have one little question regarding lateinit… Why did you introduce this in the first place? As far as I remember, you always hesitated to introduce new specialized language constructs, if they could instead be implemented in a more generic way…
    And we already have by Delegates.nonNull() for the same purpose. So why the new keyword? Is it more performant that the Delegates version? Or is it just shorter? But the Delegates version, could also be shorter, if nonNull() would be declared as top level function, doesn’t it?

    But no matter how you decide to implement it, I think there should not be two ways to do it. So if you are going to keep lateinit, you should deprecate Delegates.nonNull(); or the other way around.

    • Delegates.nonNull() does not solve this issue, because the point is to allow frameworks to inject fields, and in the case of Delegates.notNull() the field has wrong type: NotNullVar<T> instead of T

    • We are planning to introduce a generalization of the delegation mechanism in the future, if this project succeeds we’ll be able to retire lateinit or reduce it to the new mechanism, but it will take too long to wait for it, so we decided to introduce lateinit: it’s pragmatic, does not alter the language very much and is easy to deprecate if a better mechanism comes around.

  6. Jon Renner says:

    has the “it” reference in anonymous function syntax been changed?

    I mean like this:

    myArray forEach {
    println(it.name)
    }

    • Jayson Minard says:

      No… Sometimes people see it as an error when their plugin is out of sync with the Kotlin stdlib used in a project and it can’t read the library, therefore it doesn’t understand forEach and therefore doesn’t know it should be in use.

      Are you asking because you have this problem?

  7. Krtko says:

    Any word on inlined constants? For me it’s a pretty essential feature.

Comments are closed.