Basics of Kotlin Language

Samarjit Mahi
dscpgdav
Published in
12 min readDec 31, 2020

What is Kotlin?

Kotlin is an open-source, statically typed programming language. Kotlin is developed by JetBrains, the company behind the IntelliJ IDE, and other development tools. They designed Kotlin to be 100% interoperable with Java, meaning that you can use any Java libraries and frameworks in Kotlin, and vice versa

As previously mentioned, you can use Kotlin on any platform. Currently, it’s most prominent for Android app development.

Who’s Using Kotlin?

By now, Kotlin is used by too many large companies to name them all. But just to convince you that Kotlin is used in production by some of the largest tech companies in the world, here’s a selection of them:

  • Google
  • Netflix
  • Uber
  • Slack
  • Udacity
  • Evernote
  • Trello
  • Slack
  • Lyft

Many of these companies use Kotlin on Android, but also on server-side and other platforms.

Why Learn Kotlin?

there are many companies actively looking for Kotlin developers, especially in the Android development space. So having experience in Kotlin can give you an edge in the interview process.

But even without the goal of landing a Kotlin developer job, learning the language and its concepts will allow you to quickly master other modern languages such as TypeScript, Scala, and Swift because they share many language concepts.

Principles and Goals

Kotlin aims to be a readable, pragmatic, safe, and interoperable programming language:

  • Readability is supported by language features such as type inference, data classes, and infix functions. Such features allow writing concise code without losing readability.
  • Pragmatism is crucial because Kotlin is for large-scale enterprise software development. JetBrains use it themselves to develop their IDEs. Thus, Kotlin incorporates industry feedback and addresses issues of large-scale software development.
  • Safety aims to prevent common software bugs by design. This is aided by several language features such as nullable types (to prevent null pointer exceptions) and by nudging you towards best practices such as designing for inheritance.
  • Interoperability with Java is a major selling point of Kotlin and a necessary base for its widespread adoption in the JVM world. Interoperability allows Kotlin and Java to be used side by side, including the use of Java libraries or frameworks from Kotlin. For instance, the Kotlin standard library interoperates with Java by reusing the Java Collections API. Similarly, it interoperates with JavaScript in the context of Kotlin/JS.

Variables and Data Types

Read-Only vs Mutable Variables

Learn the fundamental principle of read-only and mutable variables, plus how and when to use them in Kotlin.

Mutable Variables

To declare a mutable variable, you use the var keyword:

Mutable means that the variable can be reassigned to a different value after the initial assignment.

Read-Only Variables

In contrast, a read-only variable can be declared using val (instead of var):

Read-only means that the variable cannot be reassigned once initialized.

You should prefer read-only variables to mutable ones whenever possible, i.e., whenever you don’t have to change the value after initialization.

Tip: Prefer val to var to simplify data flow and facilitate reasoning about your code.

Basic Data Types

Kotlin is a statically typed language, meaning that the data type of every expression is known at compile time.

Integers

There are four basic data types to store integer numbers of different sizes in Kotlin:

Floating Point Numbers

Additionally, Kotlin has Float and Double to store floating-point numbers up to different precision and sizes:

Two things to note:

  • The e in both values denotes exponentiation, for instance 10e3 == 1000.
  • In order to denote a Float value, you have to add the f suffix. Otherwise, Kotlin infers Double as the type of number.

Text

Kotlin uses the Char type for single characters and String for arbitrary sequences of characters:

However, you can also use multiline strings by wrapping your string into three double quotes: """<multiline string here>"""

Booleans

Finally, Kotlin uses Boolean to store either true or false:

In contrast to Java, Kotlin has no primitive types. All types discussed in this lesson are objects at runtime

Nullable Types

Thus, all objects and types you’ve seen so far in this course were non-nullable. Trying to assign null to them would cause a compile-time error:

Declaring Nullable Types

Let’s see how you can use nullable types when necessary.

The nullable counterpart of some type A is denoted as A?. For example, String? denotes a nullable string and Int? denotes a nullable integer.

If you’re familiar with union types (e.g. from TypeScript), think of these as String? = String | null. In other words, a String? is either a String or null.

Assigning null to a nullable type works as you’d expect:

Safe Call Operator

To access members of a nullable object in Kotlin, you use the safe call operator by appending a ? to the object:

The safe call operator works as follows:

  • If the object is null, it evaluates to null.
  • Otherwise, it dereferences the objects and evaluates to the value of the overall expression.

Elvis Operator

When working with nullable data, you often want to define default values that should be used in case an object is null.

In Kotlin, this is done using ?:, the so-called Elvis operator:

You can read the Elvis operator as “or else”. Here, chatName is equal to name or else "Anonymous".

This operator is useful to get rid of nullability in your code. It’s good practice to replace null values with useful default values as early as possible, as this will simplify calling code.

Conditions

For conditional control flow, Kotlin uses the if and when keywords. The syntax of if-blocks are the same as in C and Java. Similarly, the when the keyword is similar to switch in these languages but more powerful, as you will learn.

Conditions using if

Conditions with if can be written as follows:

Equality and Comparison Operators

Kotlin’s operators to formulate conditions are the following:

Logical Operators

To build up more complex conditions from primitive conditions (using the operators above), Kotlin provides the standard logical operators:

Conditions Using when

You can use when conditions to define different behaviors for a given set of distinct values. This is typically more concise than writing cascades of if-else if conditions. For instance, you can replace the if condition above with a when condition to save around 30% of the lines of code

The when the keyword is followed by the variable it compares against. Then, each line defines the value to check on the left-hand side, followed by an arrow -> and the block of code to execute if the value matches.

The code block on the right-hand side must be wrapped in curly braces unless it’s a single expression. Optionally, an else-block can be used to define a block of code to run if no other case matches.

This language construct is basically the same as switch from languages like C or Java. However, it’s more powerful since it supports more complex checks:

As you can see, there are various ways to define the value(s) to compare against:

  1. Fixed value (700)
  2. Multiple fixed values (0, 1, 2)
  3. Ranges (in 300..699)
  4. Ranges with negation (“not in range”) (!in 0..300)
  5. Function call (earthSurfaceTemp())
  6. Type check (is Int)
  7. Default case (else)

Good Practice: if vs when

From a theoretical viewpoint, if and when are equally powerful. Coming from other languages, using if will feel more natural in most cases. Using when is definitely preferable when comparing two or more distinct fixed values.

However, in aiming to write idiomatic Kotlin code, I’d encourage you to consider the when construct in more cases than the switch construct known from other languages. In many cases, a when the condition will be a more concise and readable alternative to a regular if condition, especially whenever the right-hand sides are single expressions.

In Kotlin, both if and when can be used as expressions instead of statements. An expression is a piece of code that has a value, e.g. "Kotlin", 42 * 17, or readInput(). In contrast, a statement is a piece of code with no value, such as fun foo() { ... } or while (active) { ... }. In many programming languages, if and when/switch are statements. But in Kotlin, they are expressions!

Collections

Collections are a central feature of any programming language. They allow storing multiple values — such as your list of favorite books — in one convenient data structure which can then be stored and accessed with a single variable.

The fundamental collection types you’ll master in the following lessons are:

  • Lists
  • Sets
  • Arrays*
  • Maps
  • Arrays are not part of the actual Collections API but are included here because they’re also a data structure for storing multiple elements.

Creating a List

Kotlin provides three convenient functions to initialize lists:

All three functions allow you to add any number of elements (try it out!). The main difference between them is that listOf creates a read-only list whereas mutableListOf creates a mutable list. What does this mean? With read-only lists, you cannot add or remove elements from the list after it’s created. With a mutable list, however, you can.

Read-only vs Mutable Lists

The differentiation between read-only lists and mutable lists has the same underlying intention as differentiating between val vs var: immutability. At this point, it’s important to understand how val and read-only data structures differ. They essentially represent two levels of immutability:

  • val prevents an initialized variable from being reassigned to another value. In other words, the memory address the variable points at cannot be changed; it will always point to the same memory address.
  • Read-only collections prevent adding or removing elements from an existing collection but don’t affect any variables that may point to these collections. In other words, they disallow changing values in the section of the computer’s memory that stores the collection.

Sets are linear data structures very similar to lists. However, they do have a few notable differences.

What is a Set?

Just like a list, a set is a linear data structure that contains multiple elements. However, sets are different from lists because:

  • Sets have no concept of order, meaning there is no such thing as “the third element” in a set.
  • Sets cannot contain duplicates; you cannot have a set that, for instance, contains 42 twice.

Both these properties of sets have implications for programming with them that you should be aware of when using them.

Creating a Set

The way to create a set should look familiar to you:

  • Sets cannot have duplicates, so adding an existing element has no effect
  • Sets have no concept of order, so you can’t access an element by index
  • You can create sets using setOf and mutableSetOf

What is an Array?

An array is a basic data structure in all programming languages. It stores multiple elements by placing them consecutively in memory.

What’s the Difference Between Arrays, Lists, and Sets?

Sets are easy to distinguish from both lists and arrays based on their special properties: no ordering and no duplicates.

To understand the difference between lists and arrays, we’ll have to look at the way their elements are stored and what implications this has for us as developers.

While arrays store their values in one consecutive part of computer memory, list and set elements may be spread across the memory. This has several implications:

  • Arrays are a fixed-length data structure. This is because, after the array is initially created, the next consecutive place in memory may be taken by another value. Thus, no more consecutive values can be added to the array. Not being able to add or remove elements distinguishes them from mutable lists.
  • Differences between arrays and read-only lists exist only on a lower level, i.e., in the exact API they provide, the storage structure in memory, and their resulting runtime performance.

Finally, there’s no differentiation between read-only and mutable arrays in Kotlin. Array elements can be overwritten but no elements can be added or removed, as they’re fixed in length.

A map is a collection of keys associated with values. This is a concept you may also know as dictionaries (e.g., Python) or associative arrays (e.g., PHP). Each key is associated with one unique value. This value can have any type. In particular, it may be a collection, such as a list or a nested map.

Creating a Map

Once again, Kotlin provides a convenient way to initialize (read-only) maps:

Creating a Mutable Map

As you may expect by now, Kotlin offers mutableMapOf to create a mutable map:

By using a mutable map, you can add and remove entries from the map,

  • Basic maps are created using mapOf or mutableMapOf.
  • Again, prefer read-only maps over mutable ones.
  • Kotlin provides to for creating map entries in a readable way (myKey to myValue).
  • You can add entries to a mutable map using myMap[key] = value.
  • Overwriting an existing entry works the same way (if key already exists).
  • You can remove entries from a mutable map using myMap.remove(key).

Loops

Kotlin offers the three standard types of loops:

  • while loops
  • do-while loops
  • for loops

As a programmer, loops in Kotlin will feel familiar quickly. Let’s look at a few examples, starting with while and do-while loops.

while Loops

Kotlin’s while loops have exactly the same syntax and semantics as while loops in Java or C:

The while the keyword is followed by a condition. The loop will repeat its code block until this condition evaluates to false.

This code example approximates the square root of the input up to an error margin of at most 0.001.

do-while Loops

The do-while loop checks its condition after each iteration, whereas the regular while loop checks it before each iteration. Consequently, a do-while loop always performs at least one iteration. This is why it’s typically used in cases where that first iteration gets some initial data, e.g. user input:

The advantage here is that you can limit the scope of the input variable to the loop block, which is not possible using a regular while loop. It’s good practice to minimize the scopes of your variables.

In contrast to while loops, Kotlin’s for loops work a bit differently than you may be used to from other languages.

for Loops

Kotlin’s for loops are different from many other languages because they’re used in the same manner as for-each loops (or for-in loops). Thus, you always give an iterable to the for loop over which it iterates:

for Loops vs while Loops

As with if and when, you have multiple language constructs for one concept: repeating blocks of code. So when would you prefer for over while and vice versa?

  • while loops are used when the number of iterations is not known in advance.
  • Consider again the approximation algorithm above. It may take any number of iterations to get below the required error margin because it’s not a fixed number.
  • for loops are superior when the number of iterations is known in advance.
  • In other words, the number of iterations is fixed because it’s equal to the length of the given iterable.

content reference from educative.io

--

--

Samarjit Mahi
dscpgdav
Editor for

pursuing bsc computer science from PGDAV College(DU) tech enthusiast|community lover|dancer|wannapreneur| hosting my podcast-The Samar Audio Experience