Values and variables, type inference, string templates, and control flow as expressions. The concise foundations that make Kotlin feel lighter than Java while running on the same JVM.
Kotlin distinguishes immutable values (val) from mutable variables (var), and prefers val — code that cannot change is easier to reason about. The compiler infers the type from the initializer, so you rarely write types explicitly, yet everything stays statically typed and checked. This "immutable by default, inferred, but safe" trio sets the tone for the whole language.
fun main() {
val name = "Ada" // immutable, inferred as String — can't reassign
var count = 0 // mutable — can reassign
count = count + 1
val pi: Double = 3.14 // explicit type when you want it
// name = "Bob" // COMPILE ERROR: val cannot be reassigned
println(name) // Ada
}
// prefer val. Reach for var only when the value genuinely must change.Kotlin builds strings by embedding expressions directly with the dollar sign — a simple variable with $name, or any expression in braces. It is cleaner than concatenation and is used constantly. (In this course’s source the braces are backslash-escaped so the site can render them; in real Kotlin you just write the dollar-brace.)
fun main() {
val name = "Ada"
val items = listOf("a", "b", "c")
println("Hello, $name!") // simple variable
println("You have ${items.size} items") // any expression in braces
println("Upper: ${name.uppercase()}") // method call inside a template
}
// $name for a plain variable; ${ ... } for an expression.
// Far cleaner than "Hello, " + name + "!".In Kotlin if, when, and try are expressions that produce a value, not just statements. This removes a lot of boilerplate — you assign the result of an if directly instead of declaring a variable and mutating it. when is Kotlin’s powerful switch, matching values, ranges, or types, and it is exhaustive when it needs to be.
fun classify(n: Int): String {
// 'if' returns a value — no separate declaration + assignment
val sign = if (n > 0) "positive" else if (n < 0) "negative" else "zero"
// 'when' is a supercharged switch — values, ranges, conditions
val size = when {
n < 10 -> "small"
n in 10..99 -> "medium" // range check
else -> "large"
}
return "$sign / $size"
}
fun main() = println(classify(42)) // "positive / medium"Kotlin has the usual numeric and boolean types (as real objects, no primitives to worry about), plus ranges (1..10) that make loops readable. for iterates anything iterable — ranges, lists, maps — and while works as expected. These are the everyday building blocks you will combine with the functional tools later in the course.
fun main() {
for (i in 1..5) print(i) // 12345 (inclusive range)
println()
for (i in 10 downTo 0 step 2) print("$i ") // 10 8 6 4 2 0
println()
val fruits = listOf("apple", "pear", "kiwi")
for ((index, fruit) in fruits.withIndex()) {
println("$index: $fruit") // 0: apple, 1: pear, 2: kiwi
}
var n = 3
while (n > 0) { print(n); n-- } // 321
}