Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Choices and loops

if, elif and else

fn grade(score: u32) -> text
    if score >= 90
        return "A"
    elif score >= 80
        return "B"
    elif score >= 70
        return "C"
    else
        return "F"

fn sign(x: i64) -> i64 = if x < 0 then -1 else 1

check grade(95) == "A"
check grade(71) == "C"
check grade(3) == "F"
check sign(-7) == -1

if as a statement takes a block under each branch. There is also an if expression, written on one line with then and else, as in sign. The expression form must always have an else, because it has to produce a value either way.

Comparisons cannot be chained: 0 < x < 10 is refused by the grammar. Write x in 0..10 instead.

Three loops, each with a limit

# Three kinds of loop. Each one has a limit on how often it can repeat.
fn sum_to(n: u64) -> u64
    var total: u64 = 0
    for i in 0..=n
        total += i
    return total

fn fib(n: u32) -> u64
    var a: u64 = 0
    var b: u64 = 1
    for _ in 0..n
        let t = a + b
        a = b
        b = t
    return a

fn collatz_steps(n: u64) -> u64
    var x = n
    var k: u64 = 0
    while x != 1 bound 10_000
        x = if x % 2 == 0 then x / 2 else 3 * x + 1
        k += 1
    return k

fn first_square_over(limit: u64) -> u64
    var i: u64 = 0
    loop bound 1_000
        if i * i > limit
            break
        i += 1
    return i * i

check sum_to(10) == 55
check fib(10) == 55
check collatz_steps(6) == 8
check first_square_over(50) == 64
  • for i in 0..=n runs over a range. 0..n excludes n; 0..=n includes it. A for loop can also run over a list, a map or a text.
  • while condition bound 10_000 repeats while the condition is true, at most 10,000 times. Underscores in numbers are only for reading.
  • loop bound 1_000 repeats until break, at most 1,000 times.

Why a limit? Because RCE promises that every program finishes. A for loop always has a known length. A while or loop without bound gets the default limit of 1,000,000 repetitions. A program can change that default with const LOOP_LIMIT: u64 = ....

Reaching the limit is not a hang. It is a trap with the message loop bound:

fn spin() -> u64
    var k: u64 = 0
    while true bound 10
        k += 1
    return k

check spin() == 10
$ rce check spin.rce
REFUSED spin.rce: line 7: W-INT-1 check: trap: loop bound
exit status: 1

The loop condition is always true, so the eleventh repetition traps, the check cannot be evaluated, and the program is refused.

var and assignment

let names a value that does not change. var names one that does. You change it with = or with a compound operator such as +=, -=, *=. Assignment is a statement, never an expression, so if (x = 1) is a syntax error.

What you learned

  • if statements, if ... then ... else ... expressions, ranges with in.
  • for, while ... bound and loop bound, and why each one is limited.
  • let for fixed names, var for names that change.