Skip to content

Syntax

:= infers the type; : Type = declares it explicitly:

x := 10 // inferred: int
name := "ZZ" // inferred: str
pi := 3.14 // inferred: float
count: int = 0 // explicit
names: [str] = ["Ada", "Grace"]

const marks a binding immutable — reassigning it is an error:

const LIMIT = 100
func add(a: int, b: int) -> int {
a + b
}
func main() {
println(add(3, 4)) // 7
}
main()

The return type can be omitted — it is inferred from the body. Parameters can have defaults and types can be generic (see Language Reference):

func squareArea(a: int, b: int = 2) {
return math.pow(a, b)
}
println(squareArea(2, 2)) // 1024.0
println(squareArea(2)) // uses default b = 2
struct User {id: int, name: str, email: str}
users: [User] = []
users.append(User{id: 1, name: "Ada", email: "ada@example.com"})
for user in users {
println("{user.name} <{user.email}>")
}

Methods live in impl blocks and take self first:

struct Rectangle {width: int, height: int}
impl Rectangle {
func area(self) -> int {
return self.width * self.height
}
}
rect := Rectangle{width: 3, height: 4}
println(rect.area()) // 12
if temp > 30 {
println("hot")
} else {
println("fine")
}
for i in range(10) {
println("Hello")
}
n := 3
while n > 0 {
println(n)
n = n - 1
}

if is also an expression — each branch yields a value:

func factorial(n: int) -> int {
if n <= 1 { 1 } else { n * factorial(n - 1) }
}
func describe(x: int) -> str {
match x {
0 => "zero",
1 => "one",
_ => "many"
}
}

match works on Option and Result variants too:

match int("42") {
.some(v) => println("parsed: {v}"),
.none => println("not a number"),
}
squares := map(range(1, 6), |x: int| x * x) // [1, 4, 9, 16, 25]
evens := filter(range(1, 11), |x: int| x % 2 == 0) // [2, 4, 6, 8, 10]
pairs := zip(["alice", "bob"], [95, 87])

a |> f(b) desugars to f(a, b), and works across lines:

func double(x: int) -> int { x * 2 }
func add_one(x: int) -> int { x + 1 }
result := 5 |> add_one |> double
println(result) // 12

Use _ to choose the argument position:

server := http.server()
|> http.get(_, "/", |body: str| "Hello, World!")

?? unwraps an Option, or falls back — non-Option values pass through:

name := .some("Ada")
println(name ?? "stranger") // Ada
println(42 ?? 0) // 42
name := "ZZ"
pi := 3.14159
n := 255
println("Hello, {name}!")
println("{pi:.2f}") // 3.14
println("{n:x} {n:o} {n:b}") // ff 377 11111111
println("{name} is {40 + 2}") // ZZ is 42
squared := [i ** 2 for i in range(0, 6)]
odd := [i for i in range(21) if i % 2 != 0]
import std.str
import std.math
// line comment
/* block
comment */
number1: int = 2
number2 := 2