Control Flow
Every condition — in if, a match guard, or assert — must be a Boolean. A non-Boolean is a type
error; there is no truthy coercion.
if / else
Section titled “if / else”let x = 5;if x > 10 { print("big");} else if x > 0 { print("positive");} else { print("other");}| Form | Meaning |
|---|---|
if c { … } | Runs the block when c is true |
if c { … } else { … } | Runs one of the two blocks |
if c { … } else if d { … } | Chains another condition |
if c { … } else statement | The else branch may be any one statement |
if c statement | Short form: one statement, no else |
let level = 3;let peaks = 0;if level > 2 peaks += 1;if level > 5 { print("clip"); } else print("ok");assert peaks == 1;With an else and blocks on both branches, if is an expression: its value is the last expression
of the branch taken. There is no conditional operator (c ? a : b); use this form.
let mood = "happy";let tempo = if mood == "happy" { 140 } else { 80 };assert tempo == 140;| Form | Runs |
|---|---|
loop { … } | Until break |
do N { … } | N times; N is evaluated once and truncated to an integer, and must be a Number |
do N statement | N times, one statement |
for x in source { … } | Once per element of source |
loop:label { … } | A labeled loop, for break:label and continue:label |
break leaves the innermost loop and continue starts its next iteration. With a label, they act on
the loop with that label. Only loop takes a label.
let r = 0;loop:rows { r += 1; let c = 0; loop:cols { c += 1; if c >= 2 { continue:rows; } // next row if r >= 3 { break:rows; } // leave the outer loop }}assert r == 3;
let n = 0;do 2.9 { n += 1; }assert n == 2;do 3 n += 1;assert n == 5;What for iterates
Section titled “What for iterates”| Source | Yields |
|---|---|
range(n), range(start, end) | Numbers 0 … n-1, start … end-1 |
| Array, Tuple | Each element |
| Dict | Each key, in unspecified order; dict.entries() gives [key, value] pairs |
| Iterator | Each value it yields |
| Pattern | Each event, forever — limit it with .iter().take(n) |
A String is not iterable; iterate string.iter().
for i in range(2, 5) { print(i); } // 2, 3, 4for k in #{"cutoff": 74} { print(k); } // cutofffor pair in #["a", "b"].iter().enumerate() { print(pair[0]); }for event in [C4 D4].iter().take(4) { print(event.note()); }match subject { pattern => value … } tests the arms top to bottom and evaluates the first that
matches. It is an expression, and also a statement. Arms are separated by newlines or commas; an arm
body is an expression or a { … } block whose last expression is its value.
| Pattern | Matches |
|---|---|
42, "text", true | An equal Number, String or Boolean |
C4 | A Note, or a Number with that MIDI value (and a Note pattern matches a Number subject) |
NUL | Only NUL |
_ | Anything |
name | Anything, and binds it to name in the guard and body |
(p1, p2, …) | A tuple of that length whose elements match |
pattern if condition | The pattern, when the guard is true |
fn drum_name(n) { match n { C2 => "kick" D2 => "snare" F#2 => "closed hat" x if x > 100 => "high" _ => "other" }}assert drum_name(36) == "kick";assert drum_name(120) == "high";
let where = match (0, 5) { (0, 0) => "origin", (0, y) => "on the y-axis", _ => "elsewhere",};assert where == "on the y-axis";print(drum_name(38));- Only Numbers, Strings, Booleans, Notes,
NULand tuples of those are matched by literal patterns. An Array, Dict, Pattern, function or iterator subject reaches only_or a binding. - There is no exhaustiveness check. If no arm matches at run time, it is an error.
- A guard that is not a Boolean is a runtime type error.
assert
Section titled “assert”assert condition; or assert condition, message; stops the script with an assertion error when
condition is false. The message may be any value; it is formatted as print() would show it.
let gain = 0.8;assert gain >= 0.0 && gain <= 1.0, "gain must be in [0, 1]";assert 2 > 3, "two is not greater than three";// → Assertion failed: two is not greater than threeTransport statements
Section titled “Transport statements”PLAY, PAUSE, STOP, RESET and SEEK are statements that drive the transport. See
Transport.