burn / docs

Language

Control flow

if

var temperature = 23

if (temperature > 30) {
    print("hot")
} else if temperature > 20 {
    print("warm")
} else {
    print("cold")
}
  • Parentheses around the condition are optional; the braces are not.
  • The condition must be a bool. if count { ... } with an int, or if name { ... } with a string?, is an error; write count != 0 or name != null.
  • A check in the condition narrows types inside the branch: after if (x is int) or if (name != null), x is an int and name a string there.
  • if is a statement. To choose between two values, use a match without a subject: var size = match { n > 100 => "big", else => "small" }.

while

var n = 27
var steps = 0
while n != 1 {
    n = collatz(n)
    steps += 1
}
print(steps)

fun collatz(x: int): int {
    return match {
        x % 2 == 0 => x / 2
        else => 3 * x + 1
    }
}

while true { ... } loops until a break, return or the end of the program.

for with three parts

for (var i = 0; i < 10; i += 3) {
    print(i)
}

Like in C: the first part runs once, the condition is checked before each round, and the last part runs after each round. Every part may be left out; for (;;) { ... } loops forever.

for ... in

for x in ... goes over a range, an array, a string or a map. A second name gets the position (or, for a map, the value):

for i in 0..3 {
    print(i)
}

for i in 1..=3 {
    print(i)
}

for i, fruit in ["apple", "pear"] {
    print(i, fruit)
}

for i, ch in "héllo" {
    print(i, ch)
}

var ages = {"ada": 36, "alan": 41}
for name in ages {
    print(name)
}
for name, age in ages {
    print(name, age)
}
Over One name gets Two names get
a..b, a..=b each number
an array each element the index, then the element
a string each character, as a one-character string the index, then the character
a map each key the key, then its value
  • A range's end is computed once, before the first round. A range whose end is not above its start runs zero times; there is no counting down with ranges, use a while or a three-part for.
  • An array loop reads the array's length before each round: elements pushed during the loop are visited, and the loop ends early when elements are removed.
  • A map loop visits the keys the map had when the loop started, in the order they were first added. Keys added during the loop are not visited, and removing a key that the loop has not reached yet is a runtime error when it gets there.
  • String loops go by character (Unicode code point), not by byte.
  • The loop variables only exist inside the loop, and each round has its own, so closures created in the loop keep their own value.
  • Parentheses are allowed here too: for (i in 0..3) { ... }.

break and continue

break leaves the innermost loop, and continue skips to its next round. There are no labels; to leave several loops at once, put them in a function and return.

for i in 0..3 {
    for j in 0..3 {
        if j == 1 {
            break
        }
        print(i, j)
    }
}

prints 0 0, 1 0 and 2 0.

return

return value leaves a function with a result; return alone leaves a function that has none. return at the top level of a file is an error ("return can only be used inside a function").

When a function with a return type can reach its end without a return, it stops the program at runtime with runtime error: function ended without returning a value, pointing at the closing brace. Code after a return, break or continue in the same block never runs, and the compiler warns about it ("unreachable code").

Ending the program

A program ends when its top level statements (and its main, if it has one) are done, after waiting for async tasks that are still running. To end it earlier, use std/process:

import "std/process"

fun check(args: [string]) {
    if (len(args) == 0) {
        eprint("usage: tool <file>")
        exit(2)
    }
}

check(["data.txt"])
print("checked")
  • exit(code) ends the program at once with that exit code.
  • panic(message) stops it like a runtime error: it prints runtime error: <message> with the location and exits with 1. See errors.
  • A runtime error anywhere stops the program with exit code 1.

match

match picks one of several branches by comparing a value with patterns, or by testing conditions one after another. It has its own page.