Skip to main content

match

The match block is compare a value against multiple patterns and executes the code according to the first pattern that matches.

Patterns

Literal Patterns

Match for exact values using literals like "apple", 42, @(1.5, 2.5), #bb00ff, $banana, true or null:

let x = "banana"
match x {
"apple" => Print { "It's an apple!" },
"banana" => Print { "It's a banana!" },
}

Wildcard Patterns

Use _ to match for any value. This is useful for providing a default case when no other patterns match:

let x = $banana
match x {
$apple => Print { "It's an apple!" },
$banana => Print { "It's a banana!" },
_ => Print { "It's something else!" },
}
tip

Symbols like $apple are a performant way of giving a name to things and are much faster than using Strings like "apple" for the same purpose.

Predicate Patterns

Use functions like IsNum, IsString or IsArray to match for types:

let x = "banana"
match x {
IsNum => Print { "It's a number!" },
IsString => Print { "It's a string!" },
_ => Print { "It's something else!" },
}
info

Any function that takes one argument and returns a boolean can be used as a pattern in a match block. This includes most functions in the Types category of the reference section, but you can also define your own.

Array Patterns

Use square brackets [] to match an Array. Each element of the array can be matched against a different pattern:

let x = [$banana, 100]
match x {
[$apple, _] => Print { "It's an apple!" },
[$banana, _] => Print { "It's a banana!" },
_ => Print { "It's something else!" },
}

The length of the array must be an exact match for the pattern to match:

let x = [1, 2, 3]
match x {
[_, _] => Print { "It's an array of length 2!" },
[_, _, _] => Print { "It's an array of length 3!" },
_ => Print { "It's something else!" },
}

Map Patterns

Use curly braces {} to match a Map. Each field of the map can be matched against a different pattern:

let x = { type = $banana, points = 100 }
match x {
{ type = $apple } => Print { "It's an apple!" },
{ type = $banana } => Print { "It's a banana!" },
}

Only the fields specified in the pattern are checked for a match. The Map may contain additional fields that are not specified in the pattern.

Alternative Patterns

Use | to specify multiple alternative patterns. As long as one of the alternative patterns matches, the code will be executed:

let x = "banana"
match x {
"apple" | "banana" => Print { "It's a fruit!" },
"potato" | "pumpkin" => Print { "It's a vegetable!" },
_ => Print { "It's something else!" },
}

Multiple Values

Use commas to match for multiple values at the same time:

let x = "banana"
let y = "jimmy"
match x, y {
"apple", "jimmy" => Print { "Give an apple to Jimmy!" },
"banana", "jimmy" => Print { "Give a banana to Jimmy!" },
"apple", "jane" => Print { "Give an apple to Jane!" },
"banana", "jane" => Print { "Give a banana to Jane!" },
}

The | has higher precedence than the comma. In the following example, the first pattern will match either an apple or a banana, but only if the second value is "jimmy":

let x = $banana
let y = $jimmy
match x, y {
$apple | $banana, $jimmy => Print { "Give a fruit to Jimmy!" },
$pumpkin | $potato, $jimmy => Print { "Give a vegetable to Jimmy" },
$apple | $banana, $jane => Print { "Give a fruit to Jane!" },
$pumpkin | $potato, $jane => Print { "Give a vegetable to Jane!" },
}

As commas have lower precedence than the |, use parentheses to specify alternatives to all the values:

let x = $banana
let y = $jimmy
match x, y {
($apple, $jimmy) | ($banana, $jane) => Print { "The citizens are been satisfied" },
($apple, $jane) | ($banana | $pumpkin, $jimmy) => Print { "The citizens are rioting" },
}

Match Arms

Each match arm can have a single statement or a block of code, surrounded by curly braces {}:

let x = "banana"
match x {
"apple" => Print { "It's an apple!" },
"banana" => {
Print { "It's a banana!" }
Spawn unit { BananaMonster }
},
}

Returning Values

Match blocks can also be used as expressions. The last line of each arm determines the resulting value of that arm.

let x = "banana"
let scoreChange = match x {
"apple" => 100,
"banana" => {
Print { "It's a banana!" }
Spawn unit { BananaMonster }
-100
},
}

Returning Multiple Values

To return multiple values, use commas and wrap the values in parentheses:

let x = "banana"
let color, scoreChange = match x {
"apple" => (#ff0000, 100),
"banana" => {
Print { "It's a banana!" }
Spawn unit { BananaMonster }
(#ffff00, -100)
},
}

If you call a function that returns multiple values, all values will pass through the match block:

pub fn Example1() {
x = $banana
let color, scoreChange = match x {
"apple" => GiveMeAnApple,
"banana" => GiveMeABanana,
}
}

pub fn GiveMeAnApple() -> color, scoreChange {
return #ff0000, 100
}

pub fn GiveMeABanana() -> color, scoreChange {
return #ffffff, -100
}

Declaring Variables

You can declare the result of the match expression as a new variable using the let or use keywords:

match let x = GiveMeAGift {
IsNum => Print { "The gift of numbers: " + x },
IsString => Print { "Some words for you: " + x },
}

See Local Variables to learn more about the let and use keywords.