article banner

Your first program in Kotlin

This is a chapter from the book Kotlin Essentials. You can find it on LeanPub or Amazon. It is also available as a course.

The first step in our Kotlin adventure is to write a minimal program in this language. Yes, it’s the famous "Hello, World!" program. This is what it looks like in Kotlin:

fun main() { println("Hello, World") }

This is minimal, isn't it? We need no classes (like we do in Java), no objects (like console in JavaScript), and no conditions (like in Python when we start code in the IDE). We need the main function and the println function call with some text0.

This is the most popular (but not the only) variant of the "main" function. If we need arguments, we might include a parameter of type Array<String>:

fun main(args: Array<String>) { println("Hello, World") }

There are also other forms of the main function:

fun main(vararg args: String) { println("Hello, World") }
class Test { companion object { @JvmStatic fun main(args: Array<String>) { println("Hello, World") } } }
suspend fun main() { println("Hello, World") }

Although these are all valid, let's concentrate on the simple main function as we will find it most useful. I will use it in nearly every example in this book. Such examples are usually completely executable if you just copy-paste them into IntelliJ or the Online Kotlin Playground2.

fun main() { println("Hello, World") }

All you need to do to start the main function in IntelliJ is click the green triangle which appears on the left side of the main function; this is called the "gutter icon", also known as the "Run" button.

Live templates

If you decide to test or practice the material from this book3, you will likely be writing the main function quite often. Here come live templates to help us. This is an IntelliJ feature that suggests using a template when you start typing its name in a valid context. So, if you start typing "main" or "maina" (for main with arguments) in a Kotlin file, you will be shown a suggestion that offers the whole main function.

In most my workshops, I’ve used this template hundreds of times. Whenever I want to show something new with live coding, I open a "Playground" file, select all its content (Ctrl/command + A), type "main", confirm the live template with Enter, and I have a perfect space for showing how Kotlin works.

I also recommend you test this now. Open any Kotlin project (it is best if you have a dedicated project for playing with Kotlin), create a new file (you can name it "Test" or "Playground"), and create the main function with the live template “maina”. Use the print function with some text, and run the code with the Run button.

What is under the hood on JVM?

The most important target for Kotlin is JVM (Java Virtual Machine). On JVM, every element needs to be in a class. So, you might be wondering how it is possible that our main function can be started there if it is not in a class. Let's figure it out. On the way, we will learn to find out what our Kotlin code would look like if it were written in Java. This is Java developers’ most powerful tool for learning how Kotlin works.

Let's start by opening or starting a Kotlin project in IntelliJ or Android Studio. Make a new Kotlin file called "Playground". Inside this, use the live template "maina" to create the main function with arguments and add println("Hello, World") inside.

fun main(args: Array<String>) { println("Hello, World") }

Now, select from the tabs Tools > Kotlin > Show Kotlin Bytecode.

On the right side, a new tool should open. "Show Kotlin Bytecode" shows the JVM bytecode generated from this file.

This is a great place for everyone who likes reading JVM bytecode. Since not everyone is Jake Wharton, most of us might find the "Decompile" button useful. What it does is quite funny. We’ve just compiled our Kotlin code into JVM bytecode, and this button decompiles this bytecode into Java. As a result, we can see what our code would look like if it were written in Java5.

This code reveals that our main function on JVM becomes a static function inside a class named PlaygroundKt. Where does this name come from? Try to guess. Yes, this is, by default, the file's name with the "Kt" suffix. The same happens to all other functions and properties defined outside of classes on JVM.

If we wanted to call our main function from Java code, we can call PlaygroundKt.main({}).

The name of PlaygroundKt can be changed by adding the @file:JvmName("NewName") annotation at the top of the file6. However, this does not change how elements defined in this file are used in Kotlin. It only influences how we will use such functions from Java. For example, to call our main function from Java now, we would need to call NewName.main({}).

If you have experience with Java, remember this tool as it can help you to understand:

  • How Kotlin code works on a low level.
  • How a certain Kotlin feature works under the hood.
  • How to use a Kotlin element in Java.

There are proposals to make a similar tool to show JavaScript generated from Kotlin code when our target is Kotlin/JS. However, at the time of writing this book, the best you can do is to open the generated files yourself.

Packages and importing

When our project has more than one file, we need to use packages to organize them. Packages are a way to group files together and avoid name conflicts.

A file can specify package at the top of the file using the package keyword.

package com.marcinmoskala.domain.model class User(val name: String)

If we don't specify a package, the file is in the default package. In real projects, it is recommended that package path should be the same as the directory path in our source files. Package can also include company domain in reverse order, like com.marcinmoskala. We name package using lowercase characters only.

If we want to use a function or class from another package, we need to import it. Imports are declared after the package declaration and before file elements'7 declaration. They first specify the package name, then the name of the element. We can also use the * character to import all elements from a package.

package com.marcinmoskala.domain import com.marcinmoskala.domain.model.User // or import com.marcinmoskala.domain.model.* fun useUser() { val user = User("Marcin") // ... }

Essential elements from Kotlin and Java strandard libraries are imported by default. For example, we can use println function without importing it.

Kotlin's developers rarely think about imports, because IntelliJ manage them automatically. When you use an element using IntelliJ suggestion, it will automatically add an import for you. If you use an element that is not imported, IntelliJ will suggest importing it. If you want to remove unused imports, you can use the "Remove unused imports" action (Ctrl/command + Alt + O). That is also why I decided to not show imports in most of the examples in this book.

Summary

We've learned about using main functions and creating them easily with live templates. We’ve also learned how to find out what our Kotlin code would look like if it were written in Java. For me, it seems like we have quite a nice toolbox for starting our adventure. So, without further ado, let's get on with that.

0:

The println function is implicitly imported from the standard library package kotlin.io.

2:

You can also find some chapters of this book online on the Kt. Academy website. These examples can be started and modified thanks to the Kotlin Playground feature.

3:

It makes me happy when people try to challenge what I am teaching. Be skeptical, and verify what you've learned; this is a great way to learn something new and deepen your understanding.

5:

This doesn’t always work because the decompiler is not perfect, but it is really helpful anyway.

6:

More about this in the book Advanced Kotlin, chapter Kotlin and Java interoperability.

7:

By elements in the context of Kotlin programming we mean classes, functions, properties, object, interfaces, etc. We will discuss all element types in the following chapters.