
Our
programming language is developing steadily: we released the Kotlin M3 - a big milestone, which included a lot of interesting things: from updating the
home page to supporting script mode. Our team also started active dogfudding: in the near future, more and more code in the Kotlin project will be written to Kotlin.
In this post I will briefly describe the two most interesting things that were made in M3: multi-declarations and the “splitting” of the interfaces of the collections.
Multi-declaration
')
What it looks like. Now you can write, for example, such code in Kotlin:
val map = hashMap("one" to 1, "two" to 2, "three" to 3) for ((k, v) in map) { println("$k -> $v") }
Note that in
for not declared one variable, 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 to this code:
val a = pair.component1() val b = pair.component2()
Like many other things in Kotlin, multi-declarations are based on a convention: the 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 the map as shown at the beginning: two extension-functions are declared for the Map.Entry:
fun <K, V> Map.Entry<K, V>.component1() = getKey() fun <K, V> Map.Entry<K, V>.component2() = getValue()
In the general case, for each class you need 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 the “data class”:
data class User(val name: String, val password: String) {}
The “data” annotation tells the compiler to generate several standard methods in this class: equals () / hashCode (), toString () and component1 (), component2 (). All of these functions use class properties declared in the primary constructor, for example, component1 () returns the name, and component2 () the 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 (tuples), which significantly improves the readability of the code. We decided to completely get rid of the tuples, but if you have some code on Kotlin that uses them, you can
automatically migrate it .
More about the multi-declaration in
this post in English.
Types of collections
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 the majority and thanks to which Java is such a wonderful platform).
Kotlin focuses on compatibility with existing code, so we use standard collection classes, but
make them better :

Note that the collection interfaces are divided into read-only and mutable. Good old java.util.ArrayList and HashSet are still available - these are mutable collections. But if it's just a List <String> written somewhere, you can't change it.
This helps not only to restore order, but also to simplify your life: now you can assign a List <String> to where List <Any> was expected, because immutable collections are
covariant .
Conclusion
The M3 has a lot more interesting. Read more about it
here (in English).
Installation instructions -
here (need
IntelliJ IDEA 12 ).
As always, we will be grateful for your comments / thoughts / suggestions.
Have a nice Kotlin :)