# Conditions and loops (https://docs-kyrm16yq7-ton-core-docs.vercel.app/llms/tolk/syntax/conditions-loops/content.md)



Tolk provides constructs for controlling contract flow.

* Use `if`, `assert`, and loops for conditional logic.
* Use `match` expression for [pattern matching](/llms/languages/tolk/syntax/pattern-matching/content.md).

## `if` statement [#if-statement]

`if` statement works as in most languages. `else if` and `else` blocks are optional.

```tolk
if (condition) {
    // ...
} else {
    // ...
}
```

A condition must be a [`bool`](/llms/languages/tolk/types/booleans/content.md). Integers are not implicitly converted — write the comparison explicitly:

```tolk
if (someInt != 0) {
    // ...
}
```

The same rule applies to `while`, `do while`, ternary, [`assert`](/llms/languages/tolk/syntax/exceptions/content.md), and the unary `!` operator. There is no gas overhead — the compiler strips the `!= 0` comparison off whenever it would translate to a redundant TVM instruction.

The body of `if` and `else` must be enclosed in `{ ... }`:

```tolk
// invalid
if (condition)
    someFn();

// valid
if (condition) {
    someFn();
}
```

## `assert` statement [#assert-statement]

`assert` throws an [exceptions](/llms/languages/tolk/syntax/exceptions/content.md) if a condition is false.

```tolk
assert (condition) throw ERR_CODE;
```

It is equivalent to the following form:

```tolk
if (!condition) {
    throw ERR_CODE;
}
```

## `match` expression [#match-expression]

`match` is used to perform different actions for different values of a variable. A common use case is routing values of a [union type](/llms/languages/tolk/types/unions/content.md):

```tolk
fun demo(v: A | B | C) {
    match (v) {
        A => {
            // use `v.aField` etc.
        }
        B => { /* ... */ }
        C => { /* ... */ }
    }
}
```

The `match` is equivalent to a series of `if-else` checks:

```tolk
fun demo(v: A | B | C) {
    if (v is A) {
        // use `v.aField` etc.
    }
    else if (v is B) { /* ... */ }
    else { /* ... */ }
}
```

The `match` can also be used for expressions, switch-like behavior:

```tolk
fun invertNumber(curValue: int) {
    return match (curValue) {
        1 => 0,
        0 => 1,
        else => throw ERR_UNEXPECTED,
    };
}
```

## Ternary operator [#ternary-operator]

The ternary form `condition ? when_true : when_false` is available:

```tolk
fun myAbs(v: int) {
    return v < 0 ? -v : v
}
```

If the types of `when_true` and `when_false` differ, the result becomes a union type. In most cases this is unintended, so the compiler reports an error.

```tolk
fun demo(a: int32, b: int64) {
    // instead of inferring result1 as `int32 | int64`,
    // an error "probably it's not what you expected"
    val result1 = a > b ? a : b;

    // correct: specify the type manually
    val result2: int = a > b ? a : b;

    // also correct, types are compatible
    val result3 = a > b ? a as int64 : b;
}
```

## `while` loops [#while-loops]

`while` and `do-while` loops repeatedly execute their bodies while the condition remains `true`. `while` checks the condition first and may not execute the body at all, whereas `do-while` runs the body first.

```tolk
fun demoWhile(i: int) {
    while (i > 0) {
        debug.print(i);
        i -= 1;
    }
}

fun demoDoWhile() {
    var rand: int;
    do {
        rand = random.uint256();
    } while (rand % 2 == 0);
    return rand;  // an odd number
}
```

Variables declared inside the body of `do while` are not visible in its condition. Declare them before the loop:

```tolk
var found: bool;
do {
    found = ...
} while (found);
```

`while` is used to iterate over maps:

```tolk
fun iterateOverMap(m: map<int32, Point>) {
    var r = m.findFirst();
    while (r.isFound) {
        // ...
        r = m.iterateNext(r);
    }
}
```

## `repeat` loop [#repeat-loop]

The `repeat (N)` statement executes its block `N` times:

```tolk
repeat (5) {
    // executed 5 times
}
```

`N` may be either a constant or a variable.

## `break` and `continue` [#break-and-continue]

The keywords `break` and `continue` are not supported.
