
Kotlin character
- Transfer
Hello, Habr! We hope to get to Kotlin in the foreseeable future. They could not get past this article (February).
We read and comment!
I just finished reading Bruce Tate's book “ Seven Languages in Seven Weeks ” - and since then I love it! Although I have experience working with most of the languages described in the book, I really liked how the author characterizes the languages and how these characteristics ultimately affect the practical use of the language.
Therefore, I decided to write another chapter for this book, an additional one. It will be devoted to a language that I know well enough, I understand its advantages and disadvantages: this is Kotlin.
The purpose of this article is not to teach you the Kotlin language, but to show its character. Do not try to understand her thoroughly. Better pay attention to how the features described here could affect your programming style.
A typical feature of Kotlin is that this language, in essence, does not introduce anything that has not yet been encountered in other programming languages. The fact is that Kotlin uses all these old finds in the most masterpiece way. Remember the superhero of Iron Man. Tony Stark assembled Iron Man from the simplest electronic components. Iron Man does not have such characteristic superpowers as Superman or Flash. This may seem like a weakness, however, in the long run this is a huge advantage. Let's talk about it below, but for now, let's start with the basics.

It is believed that Kotlin is intended for programming in one or another IDE - for example, in IDEA IntelliJ, Android Studio or CLion (Kotlin / Native). Here we start from the command line to demonstrate Kotlin in a simpler context. After installing Kotlin , run REPL (interactive shell) like this:

Let's try with numbers:
Simple math works. This is Kotlin / JVM running in a Java virtual machine. Integers in Java are primitives. And in Kotlin? Let's check the type of number:
Both are objects! In general, in Kotlin all entities are objects. What about java? Kotlin is fully interoperable with Java, but we see that the above types are Kotlin types. The fact is that some Kotlin built-in types cover Java types. You can see what the Java type will be in this case, using the property
This is
This property is read only. You can also define a property for reading and writing using
Please note: the type is not specified here. However, do not be fooled by this: Kotlin is a language with strong static typing. The type of the property is simply inferred from the type of the assigned value:
Enough math, let's move on to more interesting features.
Iron man was constructed because neither the police nor the army could rescue Tony Stark from the captivity of the terrorists. Tony made Iron Man to take care of his own safety, as well as expand his capabilities. He also became famous for this.
In the same way, JetBrains created Kotlin. The same company creates the most popular integrated development environments. All of their tools were originally created in Java, but the JetBrains team in practice felt all the flaws of this language. Then the company began to experiment with other languages, for example, Scala or Groovy, but even they did not satisfy them. Therefore, in the end, JetBrains decided to create their own language, with the aim that this new language should provide maximum security (so that there are no errors in the products) and scalability. In addition, Kotlin excellent propiaril JetBrains. They were already known all over the world, and when a community of specialists appeared who decided to use their awesome language, JetBrains became even cooler for them. (Here I retold this story only in the most general terms.this podcast ).
Kotlin significantly outperforms Java in terms of security. Properties must be initialized:
By default, types are not nullable:
If we want to show that this type is nullified, this is done with
True, a nullable type cannot be explicitly used:
Nullable types are similar to others, such as the optional types used in Scala. Before use, this type must be unpacked. You can use a secure call that acts just like a normal call if the property is not equal
We can also use an unsafe call that will throw an exception if the property is zero;
It is not recommended to work with unsafe calls, so you need to resort to them only in case of emergency. In projects on Kotlin they are very rare. This is a huge difference from Kotlin Java, where all calls are unsafe.
Iron Man is so cool because his combat suit is truly intelligent. He calculates the situation and warns Tony about the dangers. Kotlin is also genuinely intelligent and helps developers a lot.
One example of such intelligence is smart casting. When we check if a property is not equal to zero, we can use it as if it is really non-zero. To demonstrate some more advanced features, we will work with files. I suggest using IDEA IntelliJ ( it’s described here how to get started with it). Alternatively, you can try all these features in the online REPL . Consider an example:
As you can see, str is used explicitly (without unsafe or secure calls). That's why in the test
The principle does not only work with nullability. Smart casting is also possible:
Kotlin is perfectly supported in IDEA IntelliJ, Android Studio or CLion. In these IDEs, you get tons of tips, tricks, and support. Here is an example where the imperative processing of a collection, typical of Java, is replaced by the declarative one characteristic of Kotlin. Please note that it is the development environment that offers and performs the entire transition:

Tony Stark does not put on Iron Man as a whole if he does not need it. Usually he uses only the machine or some small components.

Kotlin's philosophy, in particular, postulates that the simple must remain simple. Here is the Hello World code on Kotlin:
This is just one function that displays text. Other typical Kotlin operations are also simple. When we do not need the whole body of a function, we can do with a single expression:
Below you will see more than once the exact same minimalist style.
Iron Man loses to Superman in some important ways. For example, laser eyes are given to Superman from birth, he can incinerate the enemy with his eyes when he pleases. Tony Stark did not equip Iron Man with eye lasers - perhaps because he did not see this as an urgent need. It is important to note here that he could easily add such a feature to Iron Man. In fact, this is also within the power of any Iron Man user. But, at the same time, other upgrades can also be hung on Iron Man, which may well be no less effective, but will cost less. This is a huge potential for flexibility. Let's move on to practice. Most programming languages provide some form of collection literals. In Python, Ruby, or Haskell, a list can be defined like this:
Why is this so important? When a collection literal is provided in the language, it also determines how the user will use the collections. All collections have some characteristics. There is an extensive discussion about which lists are better - mutable or immutable? Variables are more efficient, but immutable are much more thread safe. There are many opinions and arguments on this subject. With this in mind, would you like the list literal to generate either a mutable or immutable list? In any case, you will somehow impose on the programmer options for using the language, since the programmer will prefer to use the collection literal. Kotlin in this case leaves the freedom of choice.
Although, it is not difficult to create a mutable collection with
Please note: anyone can define their own collection, and then a top-level function that will create it:
It is easy to see above that I used a generic type parameter
Due to the fact that Kotlin uses basic features, rather than built-in literals, third-party libraries when working with Kotlin are not inferior in strength to its standard library. Another great feature that significantly democratizes libraries and frees developers hands is the so-called extension function. The bottom line is: you can define such a function so that it acts as a method:
Please note: in practice, no methods are added to the class. Extension functions are simply functions that are called in this special way. This feature may seem simple, but it is really powerful. For example, Kotlin, like other modern languages, provides functions for processing collections:
Kotlin's huge advantage is that such and similar functions are defined as extension functions. For example, take a look at the implementation
If it is not worth implementing, then you can define this function yourself. If you need any other function for processing collections, then you can easily define it. Developers often do this. For example, you can find a lot of libraries that define extension functions for Android. They simplify development for Android. Another result of this decision - at your service there are simply a lot of methods for processing collections.
It is also important to note here that
You can easily define your own collection class that implements

Tony Stark was not born a superhero, and no radioactive spider bit him. He designed Iron Man thanks to his incredible knowledge and experience. Likewise, JetBrains is a company that creates great IDEs for different languages; her people learned a lot from this work and embodied their knowledge by writing an incredible programming language. They did not bring anything new to the world of programming, but simply offered a perfectly worked out language that uses the advantages of many other programming languages - therefore, it maximizes the productivity of the developer and the highest quality of projects.
A great example of such smart design is the Kotlin tuples. When the language still existed in beta, it already supported tuples. Although, when the Kotlin team analyzed exactly how working with tuples affects the development of programs, it turned out that their influence is not always positive. That's why tuples weren’t in the release. Instead, annotations can be applied in Kotlin
This eloquently characterizes Kotlin. This is not a hodgepodge of ideas, but a truly competently made language. It contains a minimal set of the most powerful features, which in total give you amazing opportunities. In general, Kotlin leaves you much more freedom - including for co-creation.
If you want to understand Kotlin in more detail, I recommend reading the language documentation , as well as getting acquainted with the Kotlin Koans resource . If you're interested in Kotlin for Android, check out this book .
We read and comment!
I just finished reading Bruce Tate's book “ Seven Languages in Seven Weeks ” - and since then I love it! Although I have experience working with most of the languages described in the book, I really liked how the author characterizes the languages and how these characteristics ultimately affect the practical use of the language.
Therefore, I decided to write another chapter for this book, an additional one. It will be devoted to a language that I know well enough, I understand its advantages and disadvantages: this is Kotlin.
The purpose of this article is not to teach you the Kotlin language, but to show its character. Do not try to understand her thoroughly. Better pay attention to how the features described here could affect your programming style.
A typical feature of Kotlin is that this language, in essence, does not introduce anything that has not yet been encountered in other programming languages. The fact is that Kotlin uses all these old finds in the most masterpiece way. Remember the superhero of Iron Man. Tony Stark assembled Iron Man from the simplest electronic components. Iron Man does not have such characteristic superpowers as Superman or Flash. This may seem like a weakness, however, in the long run this is a huge advantage. Let's talk about it below, but for now, let's start with the basics.

The basics
It is believed that Kotlin is intended for programming in one or another IDE - for example, in IDEA IntelliJ, Android Studio or CLion (Kotlin / Native). Here we start from the command line to demonstrate Kotlin in a simpler context. After installing Kotlin , run REPL (interactive shell) like this:

Let's try with numbers:
>>> 1
1
>>> 1 + 2
3
>>> 1.0 + 2
3.0
Simple math works. This is Kotlin / JVM running in a Java virtual machine. Integers in Java are primitives. And in Kotlin? Let's check the type of number:
>>> 1::class
class kotlin.Int
>>> 1.0::class
class kotlin.Double
Both are objects! In general, in Kotlin all entities are objects. What about java? Kotlin is fully interoperable with Java, but we see that the above types are Kotlin types. The fact is that some Kotlin built-in types cover Java types. You can see what the Java type will be in this case, using the property
java
from Class
or the property of javaClass
any object:>>> 1.0::class.java
double
>>> 1.0.javaClass
double
This is
double
! Double numbers in Java are primitives. How is this possible? Kotlin employs an optimization that allows primitives to be used instead of objects when no object-oriented features are used. This happens under the hood, it does not concern the developer at all. If we need to use it double
as an object, then it will be used instead Double
. From the point of view of the developer, we can still say that "everything is an object." Define several properties:>>> val a = 1
This property is read only. You can also define a property for reading and writing using
var
:>>> var a = 1
Please note: the type is not specified here. However, do not be fooled by this: Kotlin is a language with strong static typing. The type of the property is simply inferred from the type of the assigned value:
>>> ::a.returnType
kotlin.Int
Enough math, let's move on to more interesting features.
Security
Iron man was constructed because neither the police nor the army could rescue Tony Stark from the captivity of the terrorists. Tony made Iron Man to take care of his own safety, as well as expand his capabilities. He also became famous for this.
In the same way, JetBrains created Kotlin. The same company creates the most popular integrated development environments. All of their tools were originally created in Java, but the JetBrains team in practice felt all the flaws of this language. Then the company began to experiment with other languages, for example, Scala or Groovy, but even they did not satisfy them. Therefore, in the end, JetBrains decided to create their own language, with the aim that this new language should provide maximum security (so that there are no errors in the products) and scalability. In addition, Kotlin excellent propiaril JetBrains. They were already known all over the world, and when a community of specialists appeared who decided to use their awesome language, JetBrains became even cooler for them. (Here I retold this story only in the most general terms.this podcast ).
Kotlin significantly outperforms Java in terms of security. Properties must be initialized:
>>> var a: String
error: property must be initialized or be abstract
By default, types are not nullable:
>>> var a: String = null
error: null can not be a value of a non-null type String
If we want to show that this type is nullified, this is done with
?
:>>> var a: String? = null
True, a nullable type cannot be explicitly used:
>>> a.length
error: only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
Nullable types are similar to others, such as the optional types used in Scala. Before use, this type must be unpacked. You can use a secure call that acts just like a normal call if the property is not equal
null
. If the property is equal null
, then we do not call the method, but simply return null
:>>> a = null
>>> a?.length
null
>>> a = "AAA"
>>> a?.length
3
We can also use an unsafe call that will throw an exception if the property is zero;
>>> a = null
>>> a!!.length
kotlin.KotlinNullPointerException
It is not recommended to work with unsafe calls, so you need to resort to them only in case of emergency. In projects on Kotlin they are very rare. This is a huge difference from Kotlin Java, where all calls are unsafe.
Intelligence
Iron Man is so cool because his combat suit is truly intelligent. He calculates the situation and warns Tony about the dangers. Kotlin is also genuinely intelligent and helps developers a lot.
One example of such intelligence is smart casting. When we check if a property is not equal to zero, we can use it as if it is really non-zero. To demonstrate some more advanced features, we will work with files. I suggest using IDEA IntelliJ ( it’s described here how to get started with it). Alternatively, you can try all these features in the online REPL . Consider an example:
fun smartCastingExample(str: String?) {
if(str != null)
print("Length is " + str.length)
}
As you can see, str is used explicitly (without unsafe or secure calls). That's why in the test
if(str != null)
type is driven by String?
a String
. It will also work if we exit the function with the opposite check:fun smartCastingExample(str: String?) {
if(str == null)
return
print("Length is " + str.length)
}
The principle does not only work with nullability. Smart casting is also possible:
fun smartCastingExample(any: Any?) {
if(any is String)
print("String with length " + any.length)
}
Kotlin is perfectly supported in IDEA IntelliJ, Android Studio or CLion. In these IDEs, you get tons of tips, tricks, and support. Here is an example where the imperative processing of a collection, typical of Java, is replaced by the declarative one characteristic of Kotlin. Please note that it is the development environment that offers and performs the entire transition:

Minimalism
Tony Stark does not put on Iron Man as a whole if he does not need it. Usually he uses only the machine or some small components.

Kotlin's philosophy, in particular, postulates that the simple must remain simple. Here is the Hello World code on Kotlin:
fun main(args: Array) {
print("Hello, World")
}
This is just one function that displays text. Other typical Kotlin operations are also simple. When we do not need the whole body of a function, we can do with a single expression:
fun add(a: Int, b: Int) = a + b
Below you will see more than once the exact same minimalist style.
Flexibility
Iron Man loses to Superman in some important ways. For example, laser eyes are given to Superman from birth, he can incinerate the enemy with his eyes when he pleases. Tony Stark did not equip Iron Man with eye lasers - perhaps because he did not see this as an urgent need. It is important to note here that he could easily add such a feature to Iron Man. In fact, this is also within the power of any Iron Man user. But, at the same time, other upgrades can also be hung on Iron Man, which may well be no less effective, but will cost less. This is a huge potential for flexibility. Let's move on to practice. Most programming languages provide some form of collection literals. In Python, Ruby, or Haskell, a list can be defined like this:
[1,2,3]
. Kotlin does not have such collection literals, but it provides top-level functions (those that can be used everywhere), and the Kotlin standard library has such top-level functions with which you can create collections:>>> listOf(1,2,3)
[1, 2, 3]
>>> setOf(1,2,3)
[1, 2, 3]
>>> mapOf(1 to "A", 2 to "B", 3 to "C")
{1=A, 2=B, 3=C}
Why is this so important? When a collection literal is provided in the language, it also determines how the user will use the collections. All collections have some characteristics. There is an extensive discussion about which lists are better - mutable or immutable? Variables are more efficient, but immutable are much more thread safe. There are many opinions and arguments on this subject. With this in mind, would you like the list literal to generate either a mutable or immutable list? In any case, you will somehow impose on the programmer options for using the language, since the programmer will prefer to use the collection literal. Kotlin in this case leaves the freedom of choice.
listOf
, setOf
and mapOf
give immutable collections:>>> var list = listOf(1,2,3)
>>> list.add(4)
error: unresolved reference: add
list.add(4)
^
>>> list + 4
[1, 2, 3, 4]
Although, it is not difficult to create a mutable collection with
mutableListOf
, mutableSetOf
and mutableMapOf
:>>> mutableListOf(1,2,3)
[1, 2, 3]
>>> mutableSetOf(1,2,3)
[1, 2, 3]
>>> mutableMapOf(1 to "A", 2 to "B", 3 to "C")
{1=A, 2=B, 3=C}
Please note: anyone can define their own collection, and then a top-level function that will create it:
fun specialListOf(vararg a: T): SpecialList {
// Код
}
It is easy to see above that I used a generic type parameter
T
. Do not worry. This means that you need to pass a set of elements of the same type in order to create a collection of this type. Due to the fact that Kotlin uses basic features, rather than built-in literals, third-party libraries when working with Kotlin are not inferior in strength to its standard library. Another great feature that significantly democratizes libraries and frees developers hands is the so-called extension function. The bottom line is: you can define such a function so that it acts as a method:
>>> fun Int.double() = this * 2
>>> 2.double()
4
Please note: in practice, no methods are added to the class. Extension functions are simply functions that are called in this special way. This feature may seem simple, but it is really powerful. For example, Kotlin, like other modern languages, provides functions for processing collections:
class Person(val name: String, val surname: String)
val avengers = listOf(
Person("Tony", "Stark"),
Person("Steve", "Rogers"),
Person("Bruce", "Banner"),
Person("Thor", "")
)
val list = avengers
.filter { it.surname.isNotBlank() }
.sortedWith(compareBy({ it.surname }, { it.name }))
.joinToString { "${it.name} ${it.surname}" }
print(list) // Выводит: Брюс Баннер, Стив Роджерс, Тони Старк
Kotlin's huge advantage is that such and similar functions are defined as extension functions. For example, take a look at the implementation
filter
:inline fun Iterable.filter(
predicate: (T) -> Boolean
): List {
return filterTo(ArrayList(), predicate)
}
inline fun > Iterable.filterTo(
destination: C, predicate: (T) -> Boolean
): C {
for (element in this) if (predicate(element)) destination.add(element)
return destination
}
If it is not worth implementing, then you can define this function yourself. If you need any other function for processing collections, then you can easily define it. Developers often do this. For example, you can find a lot of libraries that define extension functions for Android. They simplify development for Android. Another result of this decision - at your service there are simply a lot of methods for processing collections.
It is also important to note here that
filter
this is a function that extends not the type List
, but the interface Iterable
:public interface Iterable {
public operator fun iterator(): Iterator
}
You can easily define your own collection class that implements
Iterable
, and the language for you will add these methods to it for processing collections. Even String
implements it. That's why you can use all methods of processing collections and with String
:>>> "I like cake!".map { it.toLowerCase() }.filter { it in 'a'..'z' }.joinToString(separator = "")
ilikecake

Brief Summary
Tony Stark was not born a superhero, and no radioactive spider bit him. He designed Iron Man thanks to his incredible knowledge and experience. Likewise, JetBrains is a company that creates great IDEs for different languages; her people learned a lot from this work and embodied their knowledge by writing an incredible programming language. They did not bring anything new to the world of programming, but simply offered a perfectly worked out language that uses the advantages of many other programming languages - therefore, it maximizes the productivity of the developer and the highest quality of projects.
A great example of such smart design is the Kotlin tuples. When the language still existed in beta, it already supported tuples. Although, when the Kotlin team analyzed exactly how working with tuples affects the development of programs, it turned out that their influence is not always positive. That's why tuples weren’t in the release. Instead, annotations can be applied in Kotlin
data
. It is more universal, and the Kotlin developers had no doubt that in general it would positively affect the work with the language. Tuples are still being discussed, and perhaps someday native support for them will appear in Kotlin. However, for this to happen, the Kotlin team and the development community must make sure that such a solution is feasible.This eloquently characterizes Kotlin. This is not a hodgepodge of ideas, but a truly competently made language. It contains a minimal set of the most powerful features, which in total give you amazing opportunities. In general, Kotlin leaves you much more freedom - including for co-creation.
Home reading
If you want to understand Kotlin in more detail, I recommend reading the language documentation , as well as getting acquainted with the Kotlin Koans resource . If you're interested in Kotlin for Android, check out this book .