Reading Kotlin Code

Even being a seasoned Java developer, reading the many Kotlin examples and other existing code wasn't easy for me in the beginning - especially code that used more than one of the many Kotlin features at once.

In hindsight it would have been easier for me to get started, if I would have known the most basic syntactical features of Kotlin right from the start of my Kotlin study.

That's why I would like to walk you through a Kotlin example, which, despite its simplicity, is hard to understand for Java developers due to the combined usage of several new Kotlin features and syntax.:

    val strings = listOf("Hello", "World", "!")

    val lengths = { it.length }

    check(lengths.first() == 5)

After reading this page, you will fully understand this example (given you have solid Java knowledge) and, I assume, will start to become really excited about Kotlin's power.

Declaring Variables

Let's start with the very first line, which shows the most frequently seen syntax difference to Java: the order of tokens in a variable declaration.

Instead of Java's int i = 42, the very same declaration in Kotlin looks like this: var i : Int = 42.

Kotlin's Syntax is reverted to Java's

It looks kind of reversed compared to Java.

Variable declarations in Kotlin do not start with the variable's type but always with the keywords var or val (more about their difference follows).

Then follows the variable's name.

To finally declare its type, you note it right after a separating :.

Last not least you might, just like in Java, initialize the variable right away with an assignment.

var or val?

So, what's the difference between starting a declaration with var or val?

Basically, it's the same difference like between int i = 42 and final int i = 42 in Java.

Variables declared with var (variabel) can be reassigned later on, while those declared with val (value) can't.

This is, just like in Java, true only for the variable itself: if the object referenced by the variable is mutable, it still can be modified regardless of using val or var.

Declaration of Type (often) is Optional Thanks to Type Inference

The (very) nice thing about Kotlin is that you (in most of the cases) do not even need to declare a variable's type yourself, but let the compiler work it out itself, using type inference. That's why the aforementioned declaration in Kotlin just becomes var i = 42. So you can express var map = HashMap<String, Collection<Long>>() much more concise than Java's HashMap<String, Collection<Long>> map = HashMap<>(), which only ever became reasonably readable with the introduction of the diamond operator (<>).

In our example the Kotlin compiler automagically determines the type of strings being List<String> by looking at the type returned by listOf. So there is no need to declare it yourself, while you are perfectly able to do so, to, for example, widen the type to Collection<String>.

Ah, speaking of listOf: although I did not even mention how this "build-in" method actually is declared, as a Java developer you can easily guess its signature to be something like public static <T> List<T> listOf(T ... elements) embedded as a static method of a utility class, let's call it CollectionUtils.

We could have statically imported it (not shown), enabling us to call it without the CollectionUtils. prefix.

That's quite like it's done in Kotlin, too. Only that the signature is syntactically a bit different and that Kotlin allows us to declare functions at top level without any surrounding class. So let's head over to:

Function Declarations

Spoiler alert! This is how the declaration of listOf actually looks like:

public fun <T> listOf(vararg elements: T): List<T>

Let's walk through it step by step:

public is no surprise for Java developers, so far so good.

Kotlin is lots of fun

But already the second keyword lets even experienced developers briefly hesitate, as there is no fun in Java (no pun intended ;-) !)

Just like variable declarations, which also start with a keyword (var or val), declarations of functions do start with a keyword, namely fun, which, unsurprisingly, stands for function.

Return Type is Last

As we have seen, the type of a variable is noted after its name. The same is true for functions. Their return type follows the function's name and arguments, separated by a :. In our example that would be List<T>.

But one thing at a time: after fun there is a generic type declaration <T> - just like it would be written in Java.

The function's name listOf following right after is no deviation from Java's syntax.

But quite a few of those follow right within the brackets.

Apropos: Putting varargs outside the brackets, and looking at the declaration of the first (and sole) parameter elements, we see that its declaration very much looks like the one of normal variables: name first, then : followed by the type. Just without val or var, because in Kotlin all function parameters are implicitly val, hence "final".

The keyword vararg finally is just a simple replacement of Java's ..., you would there note between a parameter's type and name to make it a vararg.

As already mentioned, what eventually follows is the function's return type, separated by : and the function is fully declared.

Top-Level Functions

Remember me telling you that Kotlin allows to declare functions without any outer class? So you can get rid of all those "utility classes" like CollectionUtils, which just host a bunch of static methods?

listOf exactly is one of those provided by the Kotlin standard library in the package kotlin.collections. So its fully qualified name is kotlin.collections.listOf. But thanks to "static" imports, you hardly ever have to use its full name rather than just listOf.

Of course you are free to declare functions at package level yourself and benefit from that nice feature.

Named Parameters, Default Parameters & More

Functions in Kotlin offer many more nice features just as default values for arguments or referring to arguments by name when calling a function.

But as we just have started yet and or goal is to learn about the basic Kotlin syntax first, staying focussed on our example, I have to refer you to the rest of the Kotlin Guide or the official documentation about functions, if you are eager to learn more about them right now. All the others, please follow me to the next line of our example code:

    val lengths = { it.length }

High Order Functions

Now it gets really interesting and Kotlin flexes its muscles.

Looking at that line, you'll quickly notice the val keyword followed by a variable name and an initialization after the = - so we are basically dealing with a variable declaration and initialization.

Remember that strings is a list of Strings (val strings = listOf("Hello", "World", "!")).

On that, we call a method called map - but that looks a bit weird syntactically (for Java developers) and you might think I mistyped the parenthesis and inadvertently typed curly brackets instead. But what looks like a typo in reality is a very common and clever idiom in Kotlin.

But to explain it to you, I first need to introduce you to high order functions, if you don't know them already from other languages.

A higher order function is a function which either takes another function(s) as an argument or returns a function as a result.

That means, in Kotlin, you can pass a function to another function as an argument - and that's exactly what we do in our example.

The map method is part of string (that is, its type List<String>) in Kotlin. (To be more precise, it is a so called extension function of the type Iterable<T> - such extension functions are another very clever and powerful concept in Kotlin, but introducing them right here would make us loose track, so I have to ask for your patience.)

You can call map on strings.

If you haven't encountered it in Java 8+, you might ask: "What does map do anyway?"

As the name implies, it maps a value to another. More precisely, if you call map on a collection, each element will be "transformed", resulting in a new Collection with the same number of values - but each "transformed" to a new value.

Next question: "What does 'transformed' mean?". Good one!

That's exactly what map let's us determine ourselves, by accepting a function as an argument, which, as its sole argument, accepts a single list element (which is String in our case as we are calling map on a list of Strings), and returns "something".

Specifically, we could write a simple transformation function which accepts a String and returns its length (Int).

That's straightforward and we should already be able to write (or at least understand) this function, remembering the beginning of this lesson:

fun getLengthOfString(str: String): Int {
        return str.length

So far so good.

Now all we need to do is to pass this function to the map function, which in turn will call it on every element in the strings list, resulting in a list of Ints representing the single elements' String lengths.

But how do we do that?

As Kotlin supports high order functions, you can treat functions (in most cases) just like simple variables. That is, you can, for example, assign a function to a variable:

val getLengthOfString = fun(str: String): Int {
        return str.length

In contrast to a normal function declaration, the syntax slightly differs: the function itself is anonymous as we did not write a name after fun. Instead, we declare a variable called getLengthOfString whose type is function.

We now have a reference to a function stored in getLengthOfString - that's what Java does not offer.

Now we've achieved that, we simply can pass this reference to the map function as an argument:

val lengths =

This looks a bit through your Java eyes, as getLengthOfString is not just a simple variable but a real function. In Java, the closest thing to that would be a functional interface.

Anyway, that's how we pass our transformation function getLengthOfString to map, which, in turn, calls that transformation function on each and every String in our strings list, yielding a new collection of Ints containing the single String's lengths.

But what about those curly brackets in the original example?

Well, we'll get those by inlining our transformation function:

Just like any other variable, we can inline getLengthOfString just by replacing its reference with its actual value - the function itself.

Sounds complicated? It really isn't - just look at how it's done:

val lengths = String): Int {
        return str.length

We, quite literally, just replaced getLengthOfString with the function it stands for.

But, as this function is anonymous anyway and unreachable from the outer scope, we can shorten this even more using a lambda expression:

val lengths = ({ str : String -> str.length })

Those look very similar to Java's: our lambda expression takes a single str argument of type String, calls length on it to get and return that.

Looking closely, you'll notice that we did not declare the functions return type Int: as str.length' is of typeInt, the Kotlin compiler automatically determines that the function also returnsInt`s.

The powerful Kotlin compiler even allows us to skip the declaration of the str argument's type:

val lengths = ({ str -> str.length })

How does it do that? Well, looking at the type of strings - List<String> - the compiler knows that the single elements are of type String.

The declaration of map now declares that the sole argument of the passed transformation function has to be of the same type as the single elements in the list (Iterable to be more precise). How this works in detail, is out of scope right now and I will come to it later on when talking about extension functions. To not lose the thread right now, let's just assume the compiler knows that our transformation function must accept a single String as argument, just by looking at the declaration of map. So we can drop the manual type declaration of str.

But there still is more: when declaring a function with exactly one single argument, whose type is inferable by the compiler, you may drop its declaration altogether, leading to:

val lengths = ({ it.length })

Ok, the declaration is gone, neat - but what's about this it now!?

it is the reference to exactly that single aforementioned argument, whose declaration - and with that it's name - we skipped intentionally. That's we it gets the fixed name it in Kotlin. Its type is String in our example, automatically inferred by the compiler.

Now we are very close to our goal! We just need to get rid of those parenthesis.

Again, Kotlin comes to the rescue: in Kotlin, you are allowed to note the last (or only, as in our case) parameter outside the parenthesis:

val lengths = { it.length }

Frankly, this looks weird: it looks like a call to map with any arguments, followed by an obscure block of code. But what it really is, is a call of map with exactly one argument, the lambda expression {it.length}, moved out of the parenthesis, just like Kotlin allows.

Finally, for the special case of exactly one argument, moved out of the parenthesis, Kotlin allows us to not only eliminate our confusion but also the now useless parenthesis. So that we reach our goal:

val lengths = { it.length }

So we finally see the call to map with all its glory. It gets passed a single argument of type "a function, which accepts a single String as an argument, returning an Int". map iterates the strings list, calls the given function on each (String) element, putting the returned Int in a new collection, which it finally returns.


Now you see that, although it might look quite weird in the beginning, Kotlin code really is (quite) simple to understand once you step through it knowing about all the powerful, cool and clever features its creators added to it.

What's missing is the promised introduction to extension functions. As we are now done with our introductory example and extension functions are worth their very own page, please head over to the section about extension functions.