thecodex.expert · The Codex Family of Knowledge
Kotlin

Variables and Types

val doesn’t just mean “constant” in the C sense — it means the REFERENCE can’t be reassigned, and idiomatic Kotlin reaches for it by default, using var only when reassignment is genuinely part of the design.

Kotlin 2.1 val by default, var when needed Last verified:
Canonical Definition

val declares a read-only reference — assigned exactly once, though if it refers to a mutable object (like a MutableList), that object's contents can still change even though the reference itself can't be reassigned. var declares a reassignable reference. Both typically infer their type from the initializer, though an explicit type annotation (val age: Int = 30) is sometimes used for clarity or when no initializer is present yet. Idiomatic Kotlin strongly prefers val by default — IDEs and linters routinely flag a var that's never actually reassigned, nudging code toward immutability wherever reassignment isn't genuinely needed.

val vs var

Reassigning a val is a compile error, caught immediately — exactly the guarantee that makes val the safer default for anything that doesn't genuinely need to change.

Kotlinval_var.kt
val name = "Alice"      // read-only — type inferred as String
var age = 30              // reassignable — type inferred as Int

age = 31                   // fine — age is a var
// name = "Bob"            // COMPILE ERROR: val cannot be reassigned

val doesn't mean deeply immutable

The reference itself (numbers) can never point to a different list, but the LIST's contents can still change — val only locks the reference, not necessarily everything reachable through it.

Kotlinval_mutable_object.kt
val numbers = mutableListOf(1, 2, 3)
numbers.add(4)              // fine — the LIST's contents changed, numbers itself wasn't reassigned
println(numbers)            // [1, 2, 3, 4]

// numbers = mutableListOf(5, 6)   // COMPILE ERROR: numbers itself can't be reassigned

Basic types: mostly familiar, a few genuine differences

Kotlin has no primitive/object distinction visible in source code the way Java does (Int behaves consistently, whether the compiler ultimately uses a primitive int or boxes it) — and string templates with $ embed expressions directly, avoiding string concatenation entirely.

Kotlinbasic_types.kt
val count: Int = 42
val price: Double = 19.99
val isActive: Boolean = true
val initial: Char = 'K'

val message = "Count is $count, price is \$$price"   // string template — no concatenation needed
println(message)   // Count is 42, price is $19.99

Sources

1
JetBrains. Kotlin Documentation, "Basic syntax" and "Basic types," kotlinlang.org/docs/basic-syntax.html.