> ## Documentation Index
> Fetch the complete documentation index at: https://docs.truemath.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Conditionals and logic

> Branch with if and choose, repeat with loop, and combine conditions with comparison and logical operators.

These functions let an [activity](/concepts/activities) branch, repeat, and combine conditions. Comparisons and logical operators return a [boolean](/math/types/scalar-numbers#booleans) — `1` (true) or `0` (false); see [Operators and precedence](/math/functions/operators-and-precedence).

## If \[if]

```
if(comparison; true_statement; false_statement)
```

Evaluates `comparison`; returns `true_statement` if it is true, otherwise `false_statement`. Any expression can appear in any position, and `if` calls can be nested on either branch.

`comparison` uses one of the comparison operators:

| Operator | Meaning                              |
| -------- | ------------------------------------ |
| `==`     | equal to (two equals signs, not one) |
| `!=`     | not equal to                         |
| `<`      | less than                            |
| `<=`     | less than or equal to                |
| `>`      | greater than                         |
| `>=`     | greater than or equal to             |

```
if(Sales < 100000; 4; 5)          # => 4 when Sales is less than 100,000; 5 when Sales is greater than or equal to 100,000
if(Value == 25; 1; 0)             # => 1 when Value is 25, otherwise 0
```

<Note>
  Use `==` (comparison) inside conditions, not `=` (assignment). See [Operators and precedence](/math/functions/operators-and-precedence).
</Note>

### Combining conditions

Combine comparisons with `&&` (and), `||` (or), and `!` (not). A good rule of thumb is to write the condition the way you would say it out loud.

```
if(Sales > 100000 && Sales < 500000; 0.05; 0.04)            # both hold — exclusive bounds
if(Sales >= 100000 && Sales <= 500000; 0.05; 0.04)          # inclusive bounds — note >= and <=
if(Sales < 100000 || Sales > 500000; 0.04; 0.05)            # either holds
if(Sales > 100000 && Sales < 500000 || Sales > 750000 && Sales < 900000; 0.05; 0.04)
if(!(Sales >= 100000 && Sales <= 500000); 0.04; 0.05)       # ! reverses the result
```

Strict (`>`, `<`) and inclusive (`>=`, `<=`) comparisons differ exactly at the boundary value — choose deliberately.

Nesting handles more than two outcomes — here, a different result for "more than 10 over," "1–10 over," and "not over":

```
if(Your_Speed > Posted_Speed + 10; Your_Speed * 3 + 100;
   if(Your_Speed > Posted_Speed; Your_Speed * 2 + 50; 0))
```

## Choose \[choose]

```
choose(index; expression1; ...; expressionN)
```

Returns the expression at position `index` (starting with 1) — a shorthand for a chain of `if` statements. `index` must be a whole number from 1 to N, an expression that evaluates to a whole number, or a `Parameter out of range` error is returned.

```
choose(index; 25; 40; 50)   # => 25 when index is 1; 40 when 2; 50 when 3
```

## Loop \[loop]

```
loop(from; to) + (expression)
loop(from; to; step) + (expression)
```

Repeats `expression` from `from` to `to`, building a [table](/math/types/tables) with one row per iteration. It increments by `1` (or by `step`, decrementing when `to` is below `from`), and ends when the index passes `to`. Two special variables are available inside the expression:

* `index` — the current value of the loop counter. It starts at `from` and advances by `step`, so the default `loop(1; n)` runs `1, 2, … n` while `loop(1; 5; 2)` runs `1, 3, 5`.
* `last` — the value from the previous iteration (`0` on the first).

Any variable named `index` or `last` is ignored in favor of the loop's own.

```
loop(1; 5) + (10)                  => [10; 10; 10; 10; 10]
loop(1; 5) + (index)               => [1; 2; 3; 4; 5]
loop(1; 5) + (last)                => [0; 0; 0; 0; 0]
loop(1; 5) + (last + 2)            => [2; 4; 6; 8; 10]
loop(1; 5) + (last * 2 + index)    => [1; 4; 11; 26; 57]
loop(1; 5; 2) + (last * 3 + index) => [1; 6; 23]
```

### Building a series

Two loop patterns recur when projecting values over time.

**Compound growth** — a value that grows at a fixed rate each period from a first-period base:

```
loop(1; ceil(periods)) + (base * (1 + growth_rate) ^ (index - 1))
```

The `index - 1` exponent holds the first period at `base` (`^ 0` is `1`), and [`ceil`](/math/functions/rounding-and-numeric#ceiling-ceil) guards against a fractional `periods`. The result is one row per period.

**Running total** — a cumulative sum across an existing table, with `last` as the accumulator:

```
loop(1; length(series)) + (last + item(series; index))
```

Each row holds the total through that period, so the final row — `item(result; length(result))` — is the all-up total. See [`item`](/math/functions/tables#item-item) and [`length`](/math/functions/tables#length-length) in [Table functions](/math/functions/tables).
