**Control flow**
# Assignment statements
- A statement is a command to the Kotlin system to do something.
- The most basic statements are the assignment statements involving
the assignment operator = or the augmented assignment operators
```
+= -= *= /= %=
```
- An augmented assignment statement of the form
```
o=
```
is short for
```
= o
```
- Example assignment statements:
```kotlin
var a: Int
var b: Int = 7
a = b % 3
b *= a + 2
a %= b / 3
```
- Note that variable initialization uses the syntax of
normal assignment statement.
# Control flow & function call statements
- Another type of statements is the _control-flow_ statements. This type
of statements changes the order of execution of instructions from the
default linear order, depending on the value of some boolean condition.
- Examples of control-flow statements are the
_if_, _when_, _while_, _do_, and _for_ statements.
- Another type of statements is the _function calls_. Input and output
and other complex activities are done through function calls. Examples
are the _getLine()_ function call to do input, and the _println()_
function call to do output.
- We will study the control flow statements and function calls soon.
# Blocks
- A _block_ is a syntactic device for turning a sequence of
zero or more statements into one statement.
You do this by surrounding your statements in a pair of opening
and closing braces.
- Here is an example of a block statement
```kotlin
{
a = 3
b = 4 * a
}
```
- A block can also have variable declaration statements as well.
The scope of a variable declared within the block
exists from the point of declaration till the end of the block.
- It turns out you can use a block as an expression as well!
- To get a block expression, make sure the last thing you
write before the closing brace is an expression.
The value of that last expression is the value of the
block expression itself.
- Here is an example of a block expression
```kotlin
import kotlin.random.*
var n = Random.nextInt(10)
n = if (n % 2 == 1) {
println("I'm getting an odd number.")
println("I don't like odd numbers.")
println("Let me change it to an even number instead.")
n - 1
} else n
println(n)
```
# The `if` statement
- A _conditional_ is a statement that makes a decision on which
sub-statement to execute next.
- A _one-arm_ if statement has the form
```kotlin
if ()
```
- In execution, the boolean condition `` is evaluated.
If it evaluates to _true_ then `` is executed;
otherwise `` is not executed.
- A _two-arm_ if statement has the form
```kotlin
if () else
```
- In execution, the boolean condition `` is evaluated.
If it evaluates to _true_ then `` is executed;
otherwise `` is executed.
# The nested if's statement
- A use case that occurs often is an if statement whose if clause is
a non-if statement but its else clause is another if statement
whose if clause is a non-if statement but whose else clause ...
whose else clause is a non-if statement.
```kotlin
if ()
else { if ()
else { if ()
else if ()
else { ...
...
else
}
}
```
- In such a case, we usually omit the braces for readability
and write it like this:
```kotlin
if ()
else if ()
else if ()
...
else
```
# The nested if's statement's use case
- Here is an example use case of nested if's.
```kotlin
if (score > 90) grade = 'A'
else if (score > 80) grade = 'B'
else if (score > 70) grade = 'C'
else if (score > 60) grade = 'D'
else grade = 'F'
```
# The `if` expression
- Kotlin has an if expression. Its simplest form is
```kotlin
if () else
```
- The meaning of an if expression is that if `` is _true_
the if expression evaluates to ``; and if `` is _false_
the if expression evaluates to ``.
- An if expression can be used anywhere an expression is allowed.
- For example, one can write
```kotlin
val message: String = if (score > 500) "Well done!" else "Try again."
```
- **Note.** An if expression must have an else part.
In fact, a nested if can also function as an expression as long as
it has an else part at the end.
So one can write
```kotlin
val message: String = if (score > 500) "Well done!"
else if (score > 100) "Not bad"
else "Try again."
```
# The `when` statement
- Sometimes we have to make decision to choose one out of more than two
choices.
- In such a multi-way decision, Java has the switch statement.
Kotlin does not have the switch statement but it has an even more
powerful statement called the "when statement."
- There are two forms of when statements,
one form takes an argument and the other does not.
# The `when` statement with argument
- Let's look at an example `when` statement with argument.
```kotlin
when (n) {
1 -> println("smallest positive integer")
2 -> println("smallest even positive integer")
else -> println("a lot")
}
```
- There are three branches in the when statement above.
In general, there can be any number of branches.
- The `else` branch is optional and must be the last one if exists.
- In execution, the value of the argument is compared with
each branch condition from top to bottom to select exactly one branch.
The very first branch whose condition is satisfied will be selected
and its branch statement will be executed.
- The `else` condition is always satisfied.
Its statement gets executed only when
none of the above branch conditions is satisfied.
- The condition of a branch can be any arbitrary expression.
It can even be several expressions separated by commas.
In such a case, the condition is considered satisfied if
any of the comma-separated expression is equal to the when argument.
- Example
```kotlin
when (n) {
1, 2 -> println("small integer")
Random.nextInt(n) -> println("cannot happen")
else -> println("an integer greater than two")
}
```
# The `when` statement without argument
- Let's look at an example when statement without argument.
```kotlin
when {
x.isOdd() -> println("x is odd")
x.isEven() -> println("x is even")
else -> println("x is not an integer")
}
```
- Excepting for the fact that it takes no argument, its syntax is the same as that of the when statement with argument. Each branch condition except the `else` condition is a (comma-separated list of) boolean expression(s).
- In execution, each branch condition is evaluated from top to bottom to find one that evaluates to true. The very first true condition will be selected and its branch statement will be executed.
- The `else` condition is considered `true` always. Its statement gets executed only when none of the above branch conditions is satisfied.
# The `when` expression
- It turns out the when construct can be used as an expression
as well!
- The syntax of when expressions is the same as the when statement,
except that the thing that follows the arrow in each branch is
an expression instead of statement.
Here is an example of a when expression that takes no argument
```kotlin
println(when {
x.isOdd() -> "x is odd"
x.isEven() -> "x is even"
else -> "x is not an integer"
})
```
- In execution, each branch condition is evaluated
from top to bottom to find one that evaluates to true.
The very first true condition will be selected
and its branch expression will be evaluated and its value
returned as the value of the when expression.
The `else` condition is always satisfied.
Its expression gets evaluated and returned only when
none of the above branch conditions is satisfied.
# An extra rule for when expression
- A when expression that has no `else` branch will not be accepted
by the compiler unless it can prove that all branch conditions
exhaust all possibilities.
# The `while` statement.
- Kotlin's while statement is a loop construct: it repeats
the command(s) in its body so long as a boolean condition holds.
- Its form is exactly like Python's while statement except that
the two languages use different syntactic mechanisms to delimit
blocks.
- Kotlin's while statement has the form
```kotlin
while ()
```
- In execution, the boolean condition `` is evaluated.
If it evaluates to _true_, `` is executed
and the program goes back to testing the `` again.
If it evaluates to _false_, `` is skipped
and the while statement finishes.
# The `while` statement's use case
- Here is an example of the while loop:
```kotlin
var count: Int = 5
while (count >= 0) {
println(count)
count--
}
println("Boom!")
```
- It gives this output
```
5
4
3
2
1
0
Boom!
```
# The `do` statement
- Kotlin's `do` statement is another kind of loop that repeats some
action(s) so long as a boolean condition holds.
It has the form
```kotlin
do while ()
```
- In execution, `` is executed and
the boolean condition `` is evaluated.
If it evaluates to _true_,
the program goes back to executing `` and
then goes for another round of testing ``.
If it evaluates to _false_,
the `do` statement finishes.
- Notice that it's possible for the `while` statement to never execute its
body at all, but a `do` statement will execute its body at least once.
# The `for` statement
- Kotlin's `for` statement is very similar to Python's `for` statement.
It allows you to iterate over any data that implements the
Iterable interface.
- The simplest `for` statement iterates over _integer ranges_ or
_character ranges_, e.g.,
```kotlin
for (i in 1..5)
println("$i ${i*i}")
```
will output
```
1 1
2 4
3 9
4 16
5 25
```
- To exclude the right upper bound, use the word until, e.g.,
```kotlin
for (i in 1 until 5)
println("$i ${i*i}")
```
will output
```
1 1
2 4
3 9
4 16
```
- The foregoing examples show it's important to know how to generate
the arithmetic sequences.
- To generate a decreasing sequence, use the word downTo, e.g.,
```kotlin
for (c in 'd' downTo 'a')
println(c)
```
will output
```
d
c
b
a
```
- To generate a sequence that changes by more than one step at a time,
use the word step, e.g.,
```kotlin
for (c in 'e' downTo 'a' step 2)
println(c)
```
will output
```
e
c
a
```
- The keyword `step` can be used with both increasing and
decreasing sequences.
- We'll study other kinds of iterable types later.
# Nested loops
- Loops can be nested. For example, the code
```kotlin
for (i in 1..10) {
for (j in 2..12)
print("%4d".format(i*j))
println()
}
```
produces this multiplication table
```
2 3 4 5 6 7 8 9 10 11 12
4 6 8 10 12 14 16 18 20 22 24
6 9 12 15 18 21 24 27 30 33 36
8 12 16 20 24 28 32 36 40 44 48
10 15 20 25 30 35 40 45 50 55 60
12 18 24 30 36 42 48 54 60 66 72
14 21 28 35 42 49 56 63 70 77 84
16 24 32 40 48 56 64 72 80 88 96
18 27 36 45 54 63 72 81 90 99 108
20 30 40 50 60 70 80 90 100 110 120
```
# The `break` statement
- The `break` keyword allows you to exit immediately from a loop.
An example use case is
```kotlin
val wanted: Int = 42
while (true) {
...
if (thisElement == wanted)
break
...
}
```
- However, it only allows you to exit from the innermost loop.
If you want to exit from an outer loop, you have to use it in
combination with label(s) like this.
```kotlin
outer@ while () {
...
for (e in 1..10) {
...
if (hopeless)
break@outer
...
}
...
}
```
- We know the identifier `outer` is a label because it is followed
by an @ sign when it is defined. But it has the @ sign in front
when it is being referred to!
# The `continue` statement
- The `continue` statement is similar to `break` in the sense that
it allows you to jump from the innermost loop.
However, the destinations of the jump are different.
Instead of exiting the loop as in the case of break,
continue skips all remaining statements within the loop body
and goes to testing the boolean condition immediately.
- Consider this code:
```kotlin
var found: Boolean = false
while (!found) {
if (n < 0)
continue
}
```
- Let's walk through some iteration of the body of the loop.
First `` is executed, then `n < 0` is checked.
If it is false, `` is executed, followed by
``, then control goes back to checking the `!found`
condition again.
If it is true `` and `` won't be executed.
Control will go back to testing the `!found` condition immediately.
- Similar to the break statement, you can force continue to jump
from the outer loop instead of the inner loop with the help of
labels. The syntax is exactly like break with labels.
_---San Skulrattanakulchai_