Kotlin Overview

What is Kotlin?

Kotlin is a new programming language being developed mainly by JetBrains, the company known for IDEs (Integrated Development Environments) such as IntelliJ IDEA. It was announced in the summer of 2011, and today its development environment and source code are available as OSS (Open Source Software) under the Apache 2.0 license, so it can be used for free.

Code written in Kotlin is compiled into Java bytecode, the familiar class files that run on the JVM (Java Virtual Machine). Programming languages like this are called JVM languages. Scala and Groovy are also JVM languages, just like Kotlin. Kotlin is also one of the altJS languages because it supports compilation to JavaScript. It also supports Android app development.

Kotlin is a full-fledged statically typed object-oriented language with modern syntax and features such as type inference, lambda expressions, and traits. Its defining characteristic is that it lets you write code that is more concise and safer than Java.

Version 1.0 was released in February 2016, and at Google I/O in May 2017, Google announced Kotlin as an official language for Android. The Spring Framework also published Developing Spring Boot applications with Kotlin on the Spring blog in 2016, and in January 2017 introduced Kotlin support in Spring Framework 5.0.

For reference, JetBrains consists of developers from Russia and the Czech Republic, and Kotlin is the name of an island in Russia. It is said to have been named after Kotlin Island near Saint Petersburg, Russia, where many members of the development team were located.

Why Use Kotlin?

There are already countless programming languages in the world. Among them, why should it be Kotlin? Let’s look at the reasons.

The first thing to say is that Kotlin is a JVM language. Java is a very popular language used all over the world. Since its appearance in 1995, a large amount of code has been written and many systems have been operated with it. Java is still evolving today. However, to preserve backward compatibility, duplicated techniques and type-safety issues are difficult to improve. That is why JVM languages appeared. They let developers program free from some problems Java carries, while running on the highly reliable and performant JVM and making use of existing assets such as libraries and frameworks written in Java.

There are many JVM languages alone. Well-known examples include Scala and Groovy. In this competitive environment, JetBrains defines Kotlin’s design goals as follows.

  • Java compatibility
  • Compile speed at least equal to Java
  • Higher safety than Java: static checks for common mistakes such as null pointer dereferences
  • Higher conciseness than Java: support for type-variable inference, higher-order functions (closures), extension functions, mixins, first-class delegation, and more
  • Keeping expressiveness at a practical level with a simpler approach than Scala

A distinctive point is that a structure that prevents null pointer dereferences, in other words NullPointerException, is provided as a language feature (null safety). Kotlin also has other features that prevent mistakes in advance, making it harder to create bugs that easily occur in Java. You may worry that focusing on safety makes code more complicated, but Kotlin takes that point into account as well. In addition to these characteristics, Kotlin’s syntax is similar to Java, so learning cost is low, which makes it suitable for practical work.

Kotlin Features

Concise, safe, compilable to Java bytecode and JavaScript, statically typed, object-oriented, closures, and similar phrases are common descriptions of Kotlin. However, all of them are important words that directly express Kotlin’s characteristics. The following sections introduce them one by one with simple code.

Concise

No semicolon is required at the end of a line, and Kotlin supports type inference, data classes, extension functions, and more.

Kotlin code itself is simple, and its syntax, meaning the rules for writing code, is also concise. Because code is concise, there is less typing, fewer errors, and better readability, so maintenance costs can be reduced. Since the syntax is concise, learning cost is low, and code variation caused by differences in programmer skill levels can also be reduced. Example 1 below is the familiar HelloWorld written in Kotlin.

Example 1 HelloWorld in Kotlin

package sample

fun main(args: Array<String>) {
  val message = "Hello, world!"
  println(message)
}

It is a simple program that only displays a greeting on a black CLI screen, but it shows Kotlin’s characteristics. First, you can see that functions can be defined at the top level. The fun keyword is required to define a function. A function named main with an argument of type Array<String> is the entry point of a Kotlin program. The fact that the variable type comes after the variable name is also different from Java.

The message to display is assigned to the variable message. In Kotlin, variables are declared using the val keyword (or var). message is of type String, but it can be inferred from the right-hand side, so it does not need to be specified explicitly.

println is a function that writes the argument value to standard output. There is no need to put a semicolon (;) at the end of a statement. If you continue writing statements on the same line, they must be separated with ;.

It can also be written more simply as follows.

Example 2 A more concise HelloWorld

package sample

fun main() {
    println("Hello, world!")
}

Safe

Null safe: variables and function return values must explicitly indicate whether nil can be assigned.

As mentioned earlier, Kotlin is safer than Java. Types and null handling are strict. For example, in Kotlin, runtime exceptions caused by casts or null dereferences are very rare.

Kotlin distinguishes between variables that can be assigned null and variables that cannot. In Example 3 below, a compile error occurs where null is assigned to b. A variable of a normal type, here String, cannot be assigned null.

Example 3 A variable of a normal type cannot be assigned null.

val a: String = "Kotlin" // OK
val b: String = null // NG!!

The slightly changed Example 4 compiles successfully. The types of the variables c and d are String?.

Example 4 A variable whose type has ? can be assigned null.

val c: String? = "Kotlin" // OK
val d: String? = null // OK

Variables whose type has ? at the end can be assigned null. However, access to members of the object referenced by such a variable is restricted. This is to prevent NullPointerException and provide null safety. Null safety will be explained again later.

Can Compile to Java Bytecode and JavaScript

As already introduced, Kotlin is a JVM language, and its compiler compiles Kotlin code into Java bytecode. You can call Java code from Kotlin code, and you can also call Kotlin code from Java code. Example 5 shows calling the Java standard library from Kotlin code to display the contents of a text file.

Example 5 Using the Java standard library from Kotlin

import java.nio.file.Files
import java.nio.file.Paths

fun main(args: Array<String>) {
  val path = Paths.get("/memo.txt")
  val lines = Files.readAllLines(path)
  for (line in lines) {
    println(line)
  }
}

The compiler can also take Kotlin code as input and transform it into JavaScript code, so if desired, both the backend and frontend can be developed with Kotlin.

A Statically Typed Language

Kotlin is a compiled language. This does not simply mean that it runs faster than an interpreted language. Because the compiler finds source-code errors at compile time and does not generate executable code, programmers can find bugs early and create safer programs.

A statically typed programming language is a programming language where variables must be defined before they are used.

An Object-Oriented Language

Kotlin is a class-based object-oriented language. Like Java, you can create instances from defined classes. Example 6 is a simple example that defines a class and creates an instance. Anyone familiar with object-oriented languages will find the syntax familiar.

Example 5 Creating and using an instance of the User class

// User class definition
class User {
  // Property
  var id: Long = 0
  var name: String = ""

  // Method override
  override fun toString(): String {
    return "name=" + name
  }
}

fun main(args: Array<String>) {
  // Create a User instance
  // No need to write the new keyword
  val user = User()
  user.id = 12345
  user.name = "devkuma"
  println(user.toString()) // => name=devkuma
}

Unlike Java, Kotlin has no primitive types, and everything is an object. It also provides convenient features that Java does not have, such as properties, traits, and object declarations.

Closure

Kotlin has functions as first-class objects. In other words, functions can be passed as arguments to other functions or received as return values, just like other values. This lets functions be reused in finer-grained units and enables more abstract programming. This is one of the ways Kotlin stays concise.

Let’s look at Example 7, which uses the Collection Operations API provided by Kotlin’s standard library.

Example 7 Manipulating a list by passing functions as arguments

// Create the list to operate on
val list = listOf(3, 5, 2, 7, 4)
println(list) // => [3, 5, 2, 7, 4]

// Create a list where each element is multiplied by 2
val twice = list.map { e -> e * 2 }
println(twice) // => [6, 10, 4, 14, 8]

// Create a list filtered to only even elements
val even = list.filter { e -> e % 2 == 0 }
println(even) // => [2, 4]

These kinds of functions are called closures. A closure is a function that captures variables from outside that it references internally. Because it is easier to understand by looking at code, a detailed explanation of closures will be given next time.

Summary

This time, as an introduction to Kotlin, we covered its overview, features, and simple syntax. Kotlin is an open source JVM language that started from JetBrains. Its features and syntax combine conciseness and safety. It has the features desired in a modern language, including object orientation, closures, and type safety. In particular, null safety is a distinctive mechanism.

Next time, we will prepare the development environment and practice with programming examples.

Appendix: How to Learn Kotlin

There are many ways to learn Kotlin, but it is important to find the method that suits you. Some people may prefer books, some may like searching internet sites and blogs, and others may want to watch video courses.

Personally, I would recommend trying several methods. Start with a simple video course, then read web pages, and finally study books in detail to become familiar with the language. This probably does not apply only to learning Kotlin. In any field of study, you can first look at a small tree and then gradually broaden your view until you can see the whole forest.