Kotlin
2026-08-21 09:00
It showed a program, named its features, gave the philosophy.
It taught almost no syntax.
The widest unit of the module.
Everything after it assumes all of it.
Kotlin turns statements into expressions.
Function bodies. when. try.
Each time, a mutable variable becomes unnecessary.
val or var, and say what val guarantees.when.when with no argument.try as an expression.fun declares a function — at the top level, no classArray<String> is an ordinary generic typeprintln, not System.out.printlnIt makes the type optional without changing anything else.
Drop : Int and the declaration still parses.
In C-style order, there would be nothing left saying it is a declaration.
Note what is already happening: if is an expression.
Which is why Kotlin has no ternary operator. It does not need one.
The return type can go too.
Expression body → return type may be inferred.
Block body → must be declared.
Inferring a block’s type means analysing every path. A function that complicated should say what it returns.
A function that is an expression is easier to reason about
than one that assembles a result.
There is nothing to trace. The body is the answer.
Not because immutability is fashionable.
A val is a fact about the rest of the function.
Read the declaration, know the value, stop scanning for reassignments.
val prevents reassignment of the reference.
It says nothing about the object.
Immutability of the reference — that is val.
Immutability of the object — that is elsewhere, and weaker than it looks.
Note the nested quotes in the third. Handled properly.
The reference is checked at compile time.
Misspell $nmae and the code does not compile.
Nothing was given up. The field is there. The getter is there.
Java calling getName() works exactly as before.
In Java, a property is a convention — a field plus accessors named a certain way. Nothing in the language knows about it.
In Kotlin, a property is a language feature.
No field behind isSquare. Each read runs the comparison.
A property describes what the object is.
A function describes what it does, or a computation with real cost.
If a reader would be surprised that access does work — make it a function.
Kotlin does not require directories to match packages.
Several classes per file is idiomatic, not sloppy.
For large projects, follow the Java convention anyway.
enum is a soft keyword — meaningful only before class.
The only place in Kotlin where a semicolon is mandatory.
It is an expression returning a value.
There is no break, so no fall-through bug.
Branches match arbitrary objects.
The subject is a set. Order does not matter, and no extra cases were written.
The last expression of a block is its value.
Consistent across Kotlin. Worth internalising here.
when (setOf(c1, c2)) allocates a Set on every call.
And compares against a freshly allocated set in each branch it tries.
The elegant version costs objects on every call.
The fast version costs a reader’s patience.
Write the first. Reach for the second when a profiler says to.
Check with instanceof. Then cast. Then use it.
The check and the cast state the same fact twice.
The IDE even shades the background where a smart cast is active.
A val satisfies the first automatically. A var may not.
When the compiler refuses, that refusal is information.
Not merely shorter. No intermediate results, no returns, no locals.
for-in. No C-style initialiser, condition, update.
A deliberate narrowing: the three-clause loop is a reliable source of off-by-one errors.
until exists because the closed default is wrong for “n items”.
No if. No return. No mutable state.
The body never mentions entry.key.
And the index cannot get out of step with the element.
Not a coincidence. Both are conventions backed by operator functions —
which you can implement on your own types. Unit 7.
No new. Java’s exception classes.
And throw is an expression, so it fits where a value is required.
You are never required to catch or declare.
readLine and close both throw IOException. Kotlin demands nothing.
Checked exceptions are routinely caught and ignored,
or declared all the way up.
Both defeat the purpose. The guarantee was not worth the ceremony.
The value is the last expression of whichever branch ran.
Same rule as a when branch.
returnwhen is an expression → no assignment per branchtry is an expression → no var before the blockEvery one removes a mutable variable.
var disappears.val protects the reference, not the object.when beats switch on all three counts — and matching a setOf costs an allocation.Destructuring, met in the map loop — a convention, explained in unit 7.
in, doing double duty — two convention functions, explained in unit 7.
Defining and Calling Functions is about making functions pleasant to call.
Named arguments, default values, top-level functions.
And extension functions — adding methods to classes you do not own.
Kotlin · Kotlin Basics