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 and Pattern Matching

Control flow in Ferlium is expression-based: if and match both produce values. This chapter explains how their types are determined and how to use them safely and clearly.

if is an expression

An if expression always produces a value. When both branches are present, the result is the value of the selected branch.

let x = if 1 < 2 { 10 } else { 20 };
x

The condition must be a bool. Both branches must produce compatible types, because the whole if has a single type.

if true { 1 } else { 2 }        // ok: int
if true { "yes" } else { "no" } // ok: string

Branch types must agree

If the branches have different types, the program does not type check:

if true { 1 } else { "no" }   // type error

if without else

An if without else is allowed when it is used for its effect. In that case, its result type is ().

let mut a = 0;
if true { a = 1 };
a

Trying to use a value-producing branch without an else is a type error:

// type error: missing else for a non-unit branch
fn f() { if true { 1 } }

match is an expression

A match expression selects one of several branches based on a value. Like if, it produces a value.

In this chapter, we only use literal patterns and the wildcard _.

let a = 0;
match a {
    0 => 1,
    1 => 2,
    _ => 3,
}

An entry LITERAL => EXPRESSION is called an arm.

All arms must have compatible types

Every arm in a match must produce a value of the same type, because the whole match has a single type:

match 0 {
    0 => 1,
    _ => 2,
}

This is a type error:

match 0 {
    0 => 1,
    _ => "no",
}

Exhaustiveness with _

When matching on literals, use _ as the default case unless you explicitly cover all possible values. For example, matching on bool can list both cases:

match true {
    true => 1,
    false => 0,
}

What comes next

Later chapters expand pattern matching to structured data and more powerful patterns. For now, you can use literals and _ to write clear, type-safe control flow.