Created on 2025/10/26
fn main() {
message := greetMe("world")
println(message)
}
fn greetMe(name: str): str {
ret "Hello, " + name + "!"
}
Note that print and println only accept one
parameter. So a more accurate version (i.e. à la Go), would be written
like this:
use "std/fmt"
fn main() {
name := "Billy"
fmt::Println("Hello, ", name, "!")
}
let mut msg: str
let mut msg = "Hello, world!"
let mut msg: str = "Hello, world!"
let immutableMessage: str = "Hello, world!"
let immutableMessage = "Hello, world!"
let (mut x, y) = 10, 20
let (mut x, y, mut z) = true, 1, -400
let (x, _, z) = true, 1, -400
mut msg := "Hello, world!"
immutableMessage := "Hello, world!"
mut x, mut y := 10, 20
x, _, z := true, 1, -400
const Phi = 1.618
const Size: i64 = 1024
const x, y = 1, 2
const (
Pi = 3.14
E = 2.718
)
const (
Sunday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
If you have multiple constants that are around a same theme, you can use an enum instead.
num := 3 // int
num := 3. // float64
num := 3 + 4i // cmplx128
num := byte('a') // byte (alias for u8)
num := rune('a') // rune (alias for i32)
// x := [5]int([1, 2, 3, 4, 5])
x := [...]int([1, 2, 3, 4, 5])
// let x: [5]int = [1, 2, 3, 4, 5]
let x: [...]int = [1, 2, 3, 4, 5]
// let slice: []int = [2, 3, 4]
slice := [2, 3, 4]
slice := []byte("Hello")
enum FileMode {
Read,
Write,
Both,
}
enum MyEnum {
A: -20,
B, // -20
C, // -20
D: 20,
E, // 20
F: 1,
G, // 1
H, // 1
}
enum FileMode: u8 {
Read,
Write,
Both,
}
enum MyEnum {
MyVal: 10,
}
fn main() {
_ = int(MyEnum.MyVal)
_ = u8(MyEnum.MyVal)
}
enum Foo {
A,
B,
C,
}
fn main() {
x := Foo.A
match x {
| A:
println("Foo.A")
| B:
println("Foo.B")
| C:
println("Foo.C")
}
}
if day == "sunday" || day == "saturday" {
rest()
} else if day == "monday" && isTired() {
groan()
} else {
work()
}
match day {
| "sunday":
// Cases don't fall through by default
fall
| "saturday":
rest()
|:
work()
}
match {
| x > 0:
println("positive")
| x < 0:
println("negative")
|:
println("zero")
}
use "std/fmt"
mut count := 0
for count <= 10; count++ {
fmt::Println("My counter is at", count)
}
entries := ["Jack","John","Jones"]
for i, val in entries {
fmt::Printf("At position {}, the character {} is present\n", i, val)
}
mut n := 0
x := 42
for n != x {
n = guess()
}
myfunc := fn(): bool {
ret x > 10000
}
fn getMessage(): (a: str, b: str) {
ret "Hello", "World"
}
a, b := getMessage()
fn split(sum: int): (x: int, y: int) {
x = sum * 4 / 9
y = sum - x
ret
}
// Note the `!` after the function signature
fn getFirstElement(slice: []int)!: int {
if len(slice) == 0 {
error("slice is empty")
}
ret slice[0]
}
fn main() {
mut x := [1, 2, 3]
mut first := getFirstElement(x)!
x = []
first = getFirstElement(x) else { use -1 }
println(first) // -1
}
fn main() {
// A "channel"
ch := make(chan str)
// Start concurrent threads
co push("Moe", ch)
co push("Larry", ch)
co push("Curly", ch)
// Read 3 results
// Since our threads are concurrent,
// the order isn't guaranteed!
fmt::Printf("{} {} {}\n", <-ch, <-ch, <-ch)
}
fn push(name: str, ch: chan str) {
msg := "Hey, " + name + "..."
ch <- msg
}
ch := make(chan int, 2)
ch <- 1
ch <- 2
ch <- 3
// all threads are asleep - deadlock!
struct Vertex {
X: int
Y: int
}
fn main() {
mut v := Vertex{1, 2}
v.X = 4
fmt::Println(v.X, " ", v.Y)
}
v := Vertex{X: 1, Y: 2}
// Field names can be omitted
v := Vertex{1, 2}
// Y is implicit
v := Vertex{X: 1}
mut v := &Vertex{1, 2}
v.X = 2
println(*v) // {2, 2}
Useful when you want to create a struct that is guaranteed to be
unique (e.g. a a pseudo-random number generator). Think of it like a
unique_ptr in C++, or a ref object in Nim.
struct Vertex {
X: f64
Y: f64
}
impl Vertex {
fn Abs(*self): f64 {
ret math::Sqrt(self.X * self.X + self.Y * self.Y)
}
}
fn main() {
v := Vertex{1, 2}
println(v.Abs())
}
// Multiple impl blocks for a same struct are allowed
impl Vertex {
fn Scale(mut *self, f: f64) {
self.X *= f
self.Y *= f
}
}
fn main() {
mut v := Vertex{6, 12}
v.Scale(0.5) // `v` is updated
println(v)
}
trait Foo {
fn foo(*self)
}
trait Bar {
fn bar(*self)
}
trait FooBar {
Foo
Bar
}
struct Baz {}
impl FooBar for Baz {
fn foo(*self) { println("foo") }
fn bar(*self) { println("bar") }
}
fn main() {
let a: FooBar = Baz{}
a.foo()
a.bar()
let b: Foo = a
b.foo()
let c: Bar = a
c.bar()
}
fn printKind[T](value: T) {
const match type T {
| *int:
println("int pointer")
| &int:
println("int reference")
| u32:
println("u32")
| i32:
println("i32")
| u8:
println("u8")
| cmplx128:
println("cmplx128")
| cmplx64:
println("cmplx64")
| []int:
println("slice of ints")
| [5]int:
println("array of 5 ints")
|:
// cause a comptime error
panic("unexpected type")
}
}
fn main() {
let x: [5]int = [1, 2, 3, 4, 5]
printKind(x) // array of 5 ints
printKind(3+4i) // cmplx128
slice := [2, 3, 4] // slice of ints
printKind(slice)
}