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

Control Flow

Ore has no if/else. Instead, it uses when for conditionals, match for pattern matching, and loop/recur for iteration.

When

Multi-Arm Conditional

when: with indented arms replaces if-else chains. Use _ for the default case:

fn classify(x: i64) -> String:
  when:
    x > 0: "positive"
    x < 0: "negative"
    _: "zero"

Arms with multiple statements:

fn process(x: i64) -> i64:
  when:
    x > 0:
      let doubled = x * 2
      doubled + 1
    _: 0

Single Guard

A standalone when acts as an early exit or guard:

fn clamp(x: i64) -> i64:
  when x > 100: return 100
  when x < 0: return 0
  x

Match

Pattern matching on a value:

fn describe(opt: Option<i64>) -> String:
  match opt:
    Some(v): v.show()
    _: "nothing"

Literal Patterns

match x:
  0: "zero"
  1: "one"
  _: "other"

Enum Patterns

match result:
  Ok(v): v
  Err(msg): -1

Or Patterns

Multiple patterns separated by |:

match x:
  1 | 2 | 3: "small"
  4 | 5 | 6: "medium"
  _: "large"

Range Patterns

Exclusive ranges with ..:

match x:
  0..10: "single digit"
  10..100: "double digit"
  _: "big"

Guards

Add conditions with when:

match opt:
  Some(x) when x > 0: "positive"
  Some(x) when x < 0: "negative"
  Some(_): "zero"
  _: "none"

Nested Patterns

match x:
  Some(Some(v)): v
  Some(_): -1
  _: -2

Struct Patterns

match p:
  Point { x: 0, y: 0 }: "origin"
  Point { x, y }: "other"

Multi-Statement Arms

match x:
  0:
    let result = compute()
    result + 1
  _: x

Loop and Recur

Ore uses functional loops. loop creates a loop with named accumulators; recur jumps back with new values.

Accumulator Loop

fn sum_to_ten() -> i64:
  loop (i = 0, sum = 0):
    when i >= 10: sum
    recur(i + 1, sum + i)

The loop binds i and sum to initial values. recur(...) restarts the loop with new values. When a non-recur expression is reached, the loop returns that value.

Single Binding

fn double_until() -> i64:
  loop (x = 1):
    when x >= 100: x
    recur(x * 2)

Complex Loops

Loops can contain any expression, including match:

fn find(items: Vector<i64>, target: i64) -> Option<i64>:
  loop (i = 0):
    when i >= items.len(): None
    match items.get(i):
      Some(v) when v == target: Some(i)
      _: recur(i + 1)

Collecting

Build up results with an accumulator:

fn squares() -> Vector<i64>:
  loop (i = 0, result = Vector::new()):
    when i >= 5: result
    recur(i + 1, result.push(i * i))

Bare Loop

Infinite loop with explicit return:

fn repl() -> i64:
  loop:
    let line = read_line()
    when line == "quit": return 0
    process(line)

While-Style Loop

A condition after loop is checked each iteration:

fn process_connection(conn: Connection) -> i64:
  loop conn.is_alive():
    process(conn)

Return

return exits the function early with a value:

fn early_exit(x: i64) -> i64:
  when x < 0: return -1
  x * 2