A compiler tells you whether the code you wrote is syntactically valid. A good compiler, however, doesn’t do just that; it also tells you at build time whether your code might run into a logical bug later on at runtime.

One such logical bug we often make as developers is not handling the possibility that map lookups yield nothing. Being a good compiler, kotlinc knows that the entry you’re looking up in a map might not exist, and therefore errors out if it detects that you weren’t prepared for that possibility.

// Main.kt

fun main() {
    val countryFlags: Map<Country, String> =
        mapOf(
            Country.BELGIUM to "πŸ‡§πŸ‡ͺ",
            Country.MALDIVES to "πŸ‡²πŸ‡»",
            Country.PALESTINE to "πŸ‡΅πŸ‡Έ",
        )

    // ❌ Type mismatch: inferred type is String? but String was expected
    val flag: String = countryFlags[Country.BRAZIL]

    println(flag)
}

enum class Country {
    BELGIUM,
    BRAZIL,
    MALDIVES,
    PALESTINE,
}

Other compilers have absolutely no issue with concealing that fact from you as a developer.

Here’s the same code in Java:

// Main.java

import java.util.Map;

void main() {
    Map<Country, String> countryFlags = Map.of(
            Country.BELGIUM, "πŸ‡§πŸ‡ͺ",
            Country.MALDIVES, "πŸ‡²πŸ‡»",
            Country.PALESTINE, "πŸ‡΅πŸ‡Έ"
    );

    String flag = countryFlags.get(Country.BRAZIL);

    System.out.println(flag); // null
}

enum Country {
    BELGIUM,
    BRAZIL,
    MALDIVES,
    PALESTINE,
}

and in TypeScript:

// index.ts

const countryFlags: Record<string, string> = {
  BELGIUM: "πŸ‡§πŸ‡ͺ",
  MALDIVES: "πŸ‡²πŸ‡»",
  PALESTINE: "πŸ‡΅πŸ‡Έ",
};

const flag: string = countryFlags["BRAZIL"];

console.log(flag); // undefined

And that, ladies and gentlemen, is just one of things that make programming in Kotlin an absolute delight.

Kodee, the Kotlin mascot