# Topics

• Statements
• Blocks & assignment statements
• Conditional statements & expressions
• if statement & expression
• when statement & expression
• Loops
• while statement
• do statement
• for statement
• break & continue

# 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 v o= <E> is short for v = v o <E>.
• Example assignment statements:

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

{
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.

# Blocks, continued

• 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

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)

# if statement

• A conditional is a statement that makes a decision on which statement to execute next.
• A one-arm if statement has the form

if (<cond>) <stmt>
• In execution, the boolean condition <cond> is evaluated. If it evaluates to true then <stmt> is executed; otherwise <stmt> is not executed.
• A two-arm if statement has the form

if (<cond>) <stmt1> else <stmt2>
• In execution, the boolean condition <cond> is evaluated. If it evaluates to true then <stmt1> is executed; otherwise <stmt2> is executed.

# 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.

if (<cond1>) <stmt1>
else { if (<cond2>) <stmt2>
else { if (<cond3>) <stmt3>
...
else <stmtn>
...
}
}
• In such a case, we usually omit the braces for readability and write it like this:

if (<cond1>) <stmt1>
else if (<cond2>) <stmt2>
else if (<cond3>) <stmt3>
...
else <stmtn>

# Nested if’s statement’s use case

• Here is an example use case of nested if’s.

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'

# if expression

• Kotlin has an if expression. Its simplest form is

if (<cond>) <exp1> else <exp2>
• The meaning of an if expression is that if <cond> is true the if expression evaluates to <exp1>; and if <cond> is false the if expression evaluates to <exp2>.
• An if expression can be used anywhere an expression is allowed.
• For example, one can write

val message: String = if (score > 500) "Well done!" else "Try again."

# if expression, continued

• 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

val message: String = if (score > 500) "Well done!"
else if (score > 100) "Not bad"
else "Try again."

# 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.

# when statement with argument

• Let’s look at an example when statement with argument.

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.

# when statement with argument, continued

• 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

when (n) {
1, 2 -> println("small integer")
Random.nextInt(n) -> println("cannot happen")
else -> println("an integer greater than two")
}

# when statement without argument

• Let’s look at an example when statement without argument.

when {
x.isOdd() -> println("x is odd")
x.isEven() -> println("x is even")
else -> println("x is not an integer")
}
Excepting 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. Its statement gets executed only when none of the above branch conditions is satisfied.

# 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

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.

# 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 syntax for blocks.
• Kotlin’s while statement has the form

while (<cond>) <stmt>
• In execution, the boolean condition <cond> is evaluated. If it evaluates to true, <stmt> is executed and the program goes back to testing the <cond> again. If it evaluates to false, <stmt> is skipped and the while statement finishes.

# while statement’s use case

• Here is an example of the while loop:

var count: Int = 5
while (count >= 0) {
println(count)
count--
}
println("Boom!")
• It gives this output

5
4
3
2
1
0
Boom!

# 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

do <stmt> while (<cond>)
• In execution, <stmt> is executed and the boolean condition <cond> is evaluated. If it evaluates to true, the program goes back to executing <stmt> and then goes for another round of testing <cond>. 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.

# 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 and character ranges, e.g.,

for (i in 1..5)
println("$i${i*i}")

will output

1 1
2 4
3 9
4 16
5 25

# for statement, continued

• To exclude the right upper bound, use the word until, e.g.,

for (i in 1 until 5)
println("$i${i*i}")

will output

1 1
2 4
3 9
4 16

# for statement, continued

• The forgoing examples show it’s important to know how to generate the arithmetic sequences.
• To generate a decreasing sequence, use the word downTo, e.g.,

for (c in 'd' downTo 'a')
println(c)

will output

d
c
b
a

# for statement, continued

• To generate a sequence that changes by more than one step at a time, use the word step, e.g.,

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

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

# break

• The break keyword allows you to exit immediately from a loop. An example use case is

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.

outer@ while (<cond>) {
...
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!

# continue

• 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:

var found: Boolean = false
while (!found) {
<stmt0>
if (n < 0)
continue
<stmt1>
<stmt2>
}
• Let’s walk through some iteration of the body of the loop. First <stmt0> is executed, then n < 0 is checked. If it is false, <stmt1> is executed, followed by <stmt2>, then control goes back to checking the !found condition again. If it is true <stmt1> and <stmt2> 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.