Free learning resource

Source code & resources

Every code example from Kotlin from Zero to Production: Concise, Safe, Modern — free to read, copy and run. No sign-up, no catch. If you found this from one of my courses, welcome; take the code and keep building.

Source code

Code from every lesson

36 examples, in lesson order.

1. Your First Program: println and the main Function Kotlin

fun main() {
    println("A wild Charizard appears!")
}

2. val versus var: Immutability by Default Kotlin

fun main() {
    val heroName = "Aragorn"
    val heroClass = "Ranger"

    println("Hero: $heroName")
    println("Class: $heroClass")
}

3. Type Inference and Explicit Type Annotations Kotlin

val heroName: String = "Link"
val heroLevel: Int = 12
val heroPower: Double = 87.5
val isHeroAlive: Boolean = true

println("Hero: $heroName")
println("Level: $heroLevel")
println("Power: $heroPower")
println("Alive: $isHeroAlive")

4. Numbers, Booleans, and Characters Kotlin

fun main() {
    val heroHp: Int = 250
    val totalXp: Long = 9_999_999_999L
    val critMult: Double = 2.75
    val moveSpeed: Float = 6.5F

    println("Hero HP: $heroHp")
    println("Total XP: $totalXp")
    println("Crit mult: $critMult")
    println("Move speed: $moveSpeed")
}

5. Strings and String Templates Kotlin

val heroName = "Aerith"
val heroLevel = 47

// Print a plain greeting
println("Welcome back, brave adventurer!")

// Use the dollar sign to drop in values
println("Hero: $heroName")
println("Level: $heroLevel")

6. Arithmetic, Comparison, and Logical Operators Kotlin

fun main() {
    val baseDamage = 50
    val critBonus = 25
    val total = baseDamage + critBonus
    println("Total damage: $total")

    val heroHp = 100
    val hit = 35
    println("HP left: ${heroHp - hit}")

    val potions = 4
    val healPer = 30
    println("Healed: ${potions * healPer}")

    val gold = 250
    println("Each: ${gold / 4}")
    println("Extra: ${gold % 4}")
}

7. if as an Expression, Not Just a Statement Kotlin

val heroLevel = 7
val rank: String

if (heroLevel >= 10) {
    rank = "Champion"
} else {
    rank = "Apprentice"
}

println("Your rank: $rank")
println("Level required: 10")

8. when: Kotlin's Pattern-Matching Switch Kotlin

fun rateRoll(roll: Int) {
    when (roll) {
        1 -> println("Common loot!")
        2 -> println("Uncommon loot!")
        3 -> println("Rare loot!")
        else -> println("Legendary loot!")
    }
}

fun main() {
    rateRoll(1)
    rateRoll(3)
    rateRoll(7)
}

9. Null Safety and the Safe Call Operator Kotlin

fun main() {
    val equippedWeapon: String? = "Master Sword"
    val emptySlot: String? = null

    val swordLength = equippedWeapon?.length
    val slotLength = emptySlot?.length

    println("Sword name length: $swordLength")
    println("Empty slot length: $slotLength")
}

10. Smart Casts and the is Operator Kotlin

fun inspect(loot: Any) {
    if (loot is String) {
        println("Found scroll: $loot")
        println("Scroll length: ${loot.length}")
    } else {
        println("Unknown loot type!")
    }
}

fun main() {
    inspect("Ancient Map")
}

11. The for Loop and Ranges Kotlin

fun main() {
    println("Training montage begins!")
    for (level in 1..5) {
        println("Hero reached level $level!")
    }
    println("Final boss unlocked!")
}

12. while and do-while Loops Kotlin

fun main() {
    var mana = 30
    val maxMana = 100
    var tick = 1
    while (mana < maxMana) {
        mana += 15
        println("Tick $tick: mana now $mana")
        tick++
    }
    println("Mana fully restored!")
}

13. Iterating with Index Using withIndex and indices Kotlin

fun main() {
    val avengers = listOf(
        "Iron Man",
        "Thor",
        "Hulk",
        "Black Widow"
    )

    for ((slot, hero) in avengers.withIndex()) {
        println("Slot $slot: $hero ready!")
    }
}

14. break, continue, and Labelled Loops Kotlin

val rooms = listOf(
    "Hallway",
    "Library",
    "Boss Chamber",
    "Treasure Room"
)

for (room in rooms) {
    println("Entering: $room")
    if (room == "Boss Chamber") {
        println("Boss found! Halt search.")
        break
    }
}
println("Search complete.")

15. Declaring Functions with fun Kotlin

fun summonHero(): String {
    return "Aragorn enters the battle!"
}

fun main() {
    val message = summonHero()
    println(message)
}

16. Default Arguments and Named Parameters Kotlin

fun castSpell(
    name: String,
    damage: Int = 25,
    manaCost: Int = 10
) {
    println("$name hits for $damage damage!")
    println("Used $manaCost mana.")
}

fun main() {
    castSpell("Fireball", 50, 20)
}

17. Single-Expression Functions Kotlin

fun xpReward(level: Int): Int {
    return 100 * level
}

fun main() {
    val gained = xpReward(5)
    println("Defeated Goblin!")
    println("XP gained: $gained")
}

18. Local Functions and Scope Kotlin

fun main() {
    var entries = 0

    fun stepIntoDungeon() {
        entries = entries + 1
        println("Step $entries into the dungeon.")
    }

    stepIntoDungeon()
    stepIntoDungeon()
    stepIntoDungeon()
}

19. vararg and Spreading Arrays Kotlin

fun castCombo(vararg spells: String) {
    val n = spells.size
    println("Combo of $n spells:")
    for (spell in spells) {
        println("- $spell")
    }
}

fun main() {
    castCombo("Fireball", "Ice", "Thunder")

    val scroll = arrayOf("Heal", "Shield")
    castCombo(*scroll)
}

20. Lists: Read-Only versus Mutable Kotlin

fun main() {
    val starterSpells = listOf(
        "Fireball",
        "Ice Shard",
        "Healing Light"
    )

    println("Spells known:")
    for (spell in starterSpells) {
        println(" - $spell")
    }

    println("Total spells: ${starterSpells.size}")
}

21. Sets and the Uniqueness Guarantee Kotlin

fun main() {
    val party = setOf(
        "Link",
        "Zelda",
        "Link",
        "Ganon",
        "Zelda"
    )

    println("Party size: ${party.size}")
    println("Members: $party")
}

22. Maps: Key-Value Pairs the Kotlin Way Kotlin

fun main() {
    // Map each Pokemon to its level
    val partyLevels = mapOf(
        "Pikachu" to 42,
        "Charizard" to 56,
        "Snorlax" to 38
    )

    println("Party roster locked in!")
    println(partyLevels)
}

23. Common Collection Operations: filter, map, and forEach Kotlin

val loot = listOf(5, 12, 3, 88, 21, 100)
val rare = loot.filter { it >= 20 }

println("All loot: $loot")
println("Rare drops: $rare")

24. Destructuring Declarations Kotlin

fun rollLoot(): Pair<String, Int> {
    return Pair("Dragon Scale", 250)
}

fun main() {
    val (item, gold) = rollLoot()
    println("Loot drop: $item")
    println("Gold earned: $gold")
}

25. Lambdas and Higher-Order Functions Kotlin

fun main() {
    val critBonus: (Int) -> Int = { dmg -> dmg * 2 }
    val baseHit = 35
    val mega = critBonus(baseHit)
    println("Base hit: $baseHit damage")
    println("Critical strike: $mega damage")
}

26. Extension Functions and Properties Kotlin

fun String.toBattleCry(): String {
    return this.uppercase() + "!!!"
}

fun main() {
    val warrior = "for the horde"
    val mage = "fireball ready"
    println(warrior.toBattleCry())
    println(mage.toBattleCry())
}

27. Data Classes, Copy, and Destructuring Kotlin

data class Hero(
    val name: String,
    val level: Int,
    val hp: Int
)

fun main() {
    val link = Hero("Link", 12, 80)
    println(link)
}

28. Sealed Classes and Exhaustive when Kotlin

sealed class QuestResult {
    data class Victory(
        val xp: Int
    ) : QuestResult()

    data class Defeated(
        val reason: String
    ) : QuestResult()

    data class InProgress(
        val percent: Int
    ) : QuestResult()
}

29. Generics and Type Parameters Kotlin

fun <T> firstChampion(roster: List<T>): T {
    return roster.first()
}

fun main() {
    val heroes = listOf("Link", "Zelda")
    val powers = listOf(9001, 42, 100)

    val hero = firstChampion(heroes)
    val power = firstChampion(powers)

    println("Leading hero: $hero")
    println("Top power level: $power")
}

30. Sequences and Lazy Evaluation Kotlin

val heroes = listOf(
    "Link", "Zelda", "Mario",
    "Samus", "Kirby"
)

val result = heroes
    .filter {
        println("Filter: $it")
        it.length > 4
    }
    .map {
        println("Map: $it")
        it.uppercase()
    }

println("Done chaining!")
println(result)

31. Coroutines in Practice: launch, async, and await Kotlin

import kotlinx.coroutines.*

fun main() = runBlocking {
    println("Quest started!")
    launch {
        delay(500)
        println("Potion brewed!")
    }
    println("Hero fights on!")
}

32. Suspending Functions and Structured Concurrency Kotlin

import kotlinx.coroutines.*

suspend fun chargeOrb() {
    println("Orb charging...")
    delay(300)
    println("Orb at full power!")
}

fun main() = runBlocking {
    chargeOrb()
    println("Ready to fire!")
}

33. Flow: Cold Asynchronous Streams Kotlin

import kotlinx.coroutines.flow.*
import kotlinx.coroutines.runBlocking

fun spawnEnemies(): Flow<String> = flow {
    emit("Goblin spotted!")
    emit("Skeleton spotted!")
    emit("Dragon spotted!")
}

fun main() = runBlocking {
    spawnEnemies().collect { foe ->
        println("Battle starts: $foe")
    }
}

34. Resource Handling with use and try-with-resources Kotlin

import java.io.Closeable

class DungeonScroll(
    val name: String
) : Closeable {
    init {
        println("$name unfurled!")
    }

    fun reveal() {
        println("$name reveals secrets")
    }

    override fun close() {
        println("$name burns to ash")
    }
}

35. Error Handling: try/catch, Result, and runCatching Kotlin

fun parseGold(loot: String): Int {
    return loot.toInt()
}

fun main() {
    val drop = "scrambled"
    try {
        val gold = parseGold(drop)
        println("Got $gold gold!")
    } catch (e: NumberFormatException) {
        println("Loot scrambled!")
        println("Cause: ${e.message}")
    }
}

36. Delegation: by lazy, by Map, and Class Delegation Kotlin

fun loadSpellTome(): String {
    println("Decoding ancient runes...")
    return "Meteor Strike: 9999 damage"
}

val ultimateSpell: String by lazy {
    loadSpellTome()
}

fun main() {
    println("Hero opens grimoire")
    println("Cast 1: $ultimateSpell")
    println("Cast 2: $ultimateSpell")
}