Control flow in Kotlin.

Programs need to make decisions and repeat actions. We covered these concepts earlier. Now we see how Kotlin implements them. Today we learn Kotlin's control flow constructs: conditions, branches, and loops.

In Kotlin, if is not just a statement. It is an expression. It produces a value.

A statement does something. An expression produces something.

In many languages, if is a statement. You write if-else to execute different code. But you cannot use it as a value.

In Kotlin, you can: val result equals if condition then valueA else valueB.

This eliminates the need for the ternary operator. Some languages have condition question mark a colon b. Kotlin does not need it. Regular if works as an expression.

When if is used as an expression, the else branch is required. The expression must always produce a value.

The value of the if expression is the last expression in the chosen branch.

You can chain conditions with else if.

if condition1, do A. else if condition2, do B. else, do C.

The conditions are checked in order. The first true condition wins. If none are true, else executes.

As an expression: val grade equals if score greater than or equal to 90 then "A" else if score greater than or equal to 80 then "B" else if score greater than or equal to 70 then "C" else "F".

Each branch produces a value. The entire expression evaluates to one of them.

For complex branching, consider when. It is often cleaner than long if-else chains.

when is Kotlin's powerful branching construct.

It matches a value against multiple options. Think of it as a super-powered switch.

when value, then branch for option1, branch for option2, else default.

Each branch checks if the value matches. The first match wins. else handles all unmatched cases.

when is also an expression. It produces the value from the matching branch.

val description equals when x, 1 arrow "one", 2 arrow "two", else arrow "many".

Unlike Java's switch, when does not fall through. Each branch is independent.

when can match more than exact values.

Ranges: when n, in 1 to 10 arrow "small", in 11 to 100 arrow "medium", else arrow "large".

Types: when obj, is String arrow "text", is Int arrow "number", else arrow "unknown".

Multiple values: when char, vowel letters arrow "vowel", else arrow "consonant".

Arbitrary conditions: when with no value, where each branch has its own condition. x greater than 0 arrow "positive", x less than 0 arrow "negative", else arrow "zero".

when is flexible. It replaces many if-else chains with clearer syntax.

for iterates over things.

for item in collection, use item.

The loop variable item takes each value from the collection, one at a time.

Ranges: for i in 1 to 5 prints 1, 2, 3, 4, 5. The range 1 to 5 includes both endpoints.

Until: for i in 0 until 5 prints 0, 1, 2, 3, 4. Until excludes the end.

Step: for i in 0 to 10 step 2 prints 0, 2, 4, 6, 8, 10. Custom increment.

Downward: for i in 5 downTo 1 prints 5, 4, 3, 2, 1. Counting down.

for works with any iterable: lists, arrays, strings, maps, and more.

while repeats as long as a condition is true.

while condition, body. Check condition. If true, execute body. Repeat.

The condition is checked before each iteration. If false initially, the body never executes.

Use while when you do not know how many iterations in advance. Read lines until end of file. Retry until success. Wait until ready.

Make sure the condition eventually becomes false. Otherwise, infinite loop.

do-while is similar but checks the condition after.

do body while condition.

The body executes at least once. Then the condition is checked. If true, repeat.

Use do-while when you always need at least one iteration. Prompt user until valid input. Try at least once.

The difference: while may execute zero times. do-while executes at least once.

Sometimes you need to exit a loop early or skip an iteration.

break exits the loop entirely. The loop stops. Execution continues after the loop.

continue skips the rest of the current iteration. The loop continues with the next iteration.

for i in 1 to 10, if i equals 5 break, println i. This prints 1, 2, 3, 4.

for i in 1 to 5, if i equals 3 continue, println i. This prints 1, 2, 4, 5.

Use break when you found what you need and want to stop. Use continue when you want to skip certain cases.

These work in while and do-while loops as well.

return exits the current function.

It sends a value back to the caller if the function has a return type.

return can exit early. If a condition is met, return immediately. Do not continue with the rest of the function.

A find function: for i in list indices, if list at i equals target then return i. After the loop, return null.

The first return exits as soon as the target is found. No need to check the rest.

Early return can simplify code. Handle special cases at the top and return. The main logic does not need nested ifs.

Let us summarize.

if is an expression in Kotlin. It produces a value.

when is powerful branching. Matches values, ranges, types, and conditions.

for iterates over ranges, collections, and iterables.

while repeats while a condition is true. do-while runs at least once.

break exits a loop. continue skips to the next iteration.

return exits a function, optionally with a value.

These constructs give you complete control over program flow.