Learn Kotlin - Kotlin Syntax & Basic Constructs
Episode 3 of 23

Learn Kotlin - Kotlin Syntax & Basic Constructs

This episode masters the core Kotlin syntax: val and var declarations, data types and string templates, control flow with if and when, loops and ranges, functions with default arguments, plus extension functions and infix notation.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

You already understood Kotlin's architecture in episode 2. Now it's time to move up a level: master the syntax you'll write every day. Episode 3 covers variables, data types, string templates, control flow, functions, and up to extension functions and infix notation.

The biggest difference from Java will be felt here: Kotlin designs its syntax to be expressive and concise. if can be an expression, when replaces switch with something far more powerful, and functions can have default arguments that eliminate overload boilerplate.

Every concept in this episode is used directly in all the following episodes, so make sure you truly understand it before moving on.

Variables and Data Types

val vs var

Kotlin distinguishes read-only and mutable variables: val for values that can't change after initialization, and var for values that can. Get into the habit of using val as much as possible — the code is safer and easier to reason about:

Kotlinval and var
val nama = "Arman"
var umur = 26
umur = 27

In the declarations above: nama can't be changed after initialization, while umur can. The compiler will reject any attempt to reassign a val variable — protection that prevents bugs at compile time.

Basic Data Types and String Templates

Kotlin's basic types include Int, Long, Double, Float, Boolean, Char, and String. String templates let you insert expressions directly into text:

KotlinString templates
val produk = "kopi"
val harga = 15_000
println("Harga $produk adalah $harga rupiah")
println("Harga total: ${harga * 2}")

The $produk syntax inserts a variable's value, while ${harga * 2} inserts the result of an expression. These string templates are far more comfortable than concatenation with the plus sign.

Control Flow

if as an Expression

In Kotlin, if is an expression that returns a value — unlike Java, where it's only a statement:

Kotlinif as an expression
val nilai = 75
val status = if (nilai >= 60) "Lulus" else "Tidak lulus"
println(status)

Because if returns a value, you can assign it directly to a variable. There's no ternary operator in Kotlin — the if expression replaces it more clearly.

when as a Replacement for switch

when is far more powerful than Java's switch: it can match values, ranges, types, and conditions without needing a break:

Kotlinwhen with ranges
val skor = 85
when (skor) {
    in 90..100 -> println("Sempurna")
    in 75..89 -> println("Bagus")
    in 60..74 -> println("Cukup")
    else -> println("Perlu belajar lagi")
}

The in 90..100 syntax uses a range that writes a range of numbers concisely. when evaluates the matching branch, and the else branch handles all other cases.

Loops and Ranges

Kotlin uses for with clean iteration:

KotlinLoops and ranges
for (i in 1..5) {
    println(i)
}
for (i in 10 downTo 1 step 2) {
    print("$i ")
}
while (true) {
    println("loop sampai break")
    break
}

The range 1..5 covers the numbers 1 through 5, 10 downTo 1 goes backward, and step 2 jumps by two. This combination writes expressive loops without boilerplate.

Functions

Default Arguments and Named Parameters

Functions in Kotlin can have default values so callers can omit optional parameters. Named parameters make calls more readable:

KotlinDefault and named arguments
fun buatEmail(penerima: String, subjek: String = "Tanpa judul", cc: String? = null): String {
    return "Email untuk $penerima, subjek $subjek, cc $cc"
}
 
val email = buatEmail(penerima = "user@example.com", subjek = "Halo")

The call above uses named arguments and only mentions two of the three parameters — the others use their default values. This replaces many of the overloads you'd normally write in Java.

Single-expression Functions

For simple functions, Kotlin allows a single expression body without curly braces:

KotlinSingle-expression function
fun luasPersegi(sisi: Int): Int = sisi * sisi
 
fun sapa(nama: String): String = "Halo, $nama!"

The functions above return the result of their expression directly. With type inference, the return type can be omitted for single-expression functions, making them even more concise. You can test all the examples in this episode with kotlinc Main.kt -include-runtime -d main.jar and then run the resulting JAR.

Extension Functions and Infix Notation

Adding Functions to Existing Types

Extension functions let you add a function to a type without changing its original definition. This is one of the most used features across the Kotlin ecosystem:

KotlinExtension function
fun String.hitungKata(): Int = this.split(" ").size
 
val kalimat = "belajar kotlin itu menyenangkan"
println(kalimat.hitungKata())

String.hitungKata() treats String as if it had a hitungKata function. The receiver this inside the body refers to the String it was called on. You'll encounter these extension functions in many libraries, including kotlinx and Android.

Infix Notation

Functions declared with the infix keyword can be called without a dot and parentheses, creating syntax that resembles natural language:

KotlinInfix function
infix fun Int.kali(angka: Int): Int = this * angka
 
val hasil = 6 kali 7
println(hasil)

The call 6 kali 7 reads like a sentence. Infix notation is useful for functions that read naturally like this, and is used in operations like map with key-value pairs in episode 5.

Closing

Episode 3 completes your core syntax toolkit: val and var, string templates, if and when as expressions, loops with ranges, functions with default arguments, and extension functions and infix notation. All of these are tools you'll use in every following episode.

The key takeaways:

  • Use val by default, var only when you truly need it.
  • if and when are expressions that can return values.
  • String templates use $variable and ${expression}.
  • Default arguments eliminate the need for repeated overloads.
  • Extension functions add functionality to a type without changing its original definition.
  • Infix notation makes function calls read like sentences.

In episode 4 we'll discuss classes, objects, and OOP — class declarations, constructors and properties, visibility modifiers, data classes, sealed classes, inheritance, interfaces, and companion objects and the singleton pattern. It's time to build your object world with Kotlin.