Kotlin M3 released

    Our programming language is developing steadily: we released Kotlin M3 - a large milestone, which included a lot of interesting things: from updating the home page to supporting script mode. Our team also started active “dogfooding”: in the near future more and more code in the Kotlin project will be written in Kotlin.

    In this post, I will briefly describe two of the most interesting things that were done in M3: multi-declarations and “splitting” of collection interfaces.


    What does it look like. Now in Kotlin you can write, for example, the following code:

    val map = hashMap("one" to 1, "two" to 2, "three" to 3)
    for ((k, v) in map) {
        println("$k -> $v")

    Note that not one variable is declared in for , but two, in parentheses. This is one example of multiple declarations, or “multi-declarations”. A simpler example:

    val (a, b) = pair

    As a result of this declaration, two variables appear that can be used completely independently of each other.

    How it works. The declaration from the last example is translated into the following code:
    val a = pair.component1()
    val b = pair.component2()

    Like many other things in Kotlin, multi-declarations rely on convention: componentN () functions are called by name, that is, they can be declared both in the pair class and outside of it as extensions . This makes it possible to bypass map as shown at the beginning: two extension functions are declared for Map.Entry:
    fun  Map.Entry.component1() = getKey()
    fun  Map.Entry.component2() = getValue()

    In the general case, each class needs to implement such functions in its own way, but there is one very common case: when a class simply stores data and does nothing else. This is called a “data class”:

    data class User(val name: String, val password: String) {}

    The “data” annotation tells the compiler that several standard methods must be generated in this class: equals () / hashCode (), toString () and component1 (), component2 (). All these functions use the class properties declared in the primary constructor, for example, component1 () returns name, and component2 () returns password:

    val (name, pass) = getUser()

    Data classes, in particular, make it possible to return several values ​​from a function without resorting to the use of tuples, which greatly improves the readability of the code. We decided to completely get rid of tuples, but if you have some kind of Kotlin code that uses them, you can automatically migrate it .

    More about multi-declarations in this post in English.

    Collection Types

    Collections are used everywhere and always, therefore the convenience of a programming language depends on the design of the corresponding part of the library. That is why many "alternative" languages ​​on the Java platform use their own collections that are incompatible with the standard ones, which creates various difficulties when using Java libraries (which are the majority and due to which Java is such a wonderful platform).

    Kotlin emphasizes compatibility with existing code, so we use standard collection classes, but we do them better :

    Note that collection interfaces are divided into read-only and mutable. The good old java.util.ArrayList and HashSet are still available - these are mutable collections. But if it just says List, you cannot change it.

    This helps not only to put things in order, but also to simplify your life: now you can assign List to where List was expected, because immutable collections are covariant .


    M3 includes a lot of other interesting things. You can read more about this here (in English).

    Installation instructions are here (need IntelliJ IDEA 12 ).

    As always, we will be grateful for your comments / thoughts / suggestions. Have a nice Kotlin :)

    Also popular now: