The Ore Programming Language
Ore is a statically-typed, compiled systems language with algebraic effects and automatic memory management via Perceus reference counting.
Design Principles
- Explicit memory. Three pointer types:
[*]T(heap, RC-managed),[]T(slice view),*T(raw pointer). No hidden allocations. - Two operators, clear roles.
:=binds and rebinds names.<-mutates memory at a location. Never confused. - Everything is
name :: thing. Functions, data types, effects, constants — all defined with::. - Public by default. Items are public unless marked
pvt. - Effects are explicit. Side effects tracked in function signatures via effect rows.
- No null.
?Tfor optional values,!Tfor error unions. - One data keyword.
datareplaces struct and enum — everything is a sum type. - UFCS.
x.f()isf(x). No methods, no traits — just functions. - Operators are intrinsics.
+,-,*, etc. are compiler built-ins. - Compile-time safety. Argus (escape analysis + borrow checking) prevents dangling references at compile time. No runtime checks, no lifetime annotations.
Syntax Overview
Ore uses indentation with optional curly braces (layout rule):
greet :: fn(name: []const u8)
print(name)
greet :: fn(name: []const u8) { print(name) }
A Quick Example
Shape :: data
Circle .{ f64 }
Rect .{ f64, f64 }
area :: fn(s: Shape) -> f64
match s
Shape::Circle.{ r } { 3.14 * r * r }
Shape::Rect.{ w, h } { w * h }
main :: fn() -> !i32
0
Binding and Mutation
// :: is compile-time constant (rodata)
PI :: 3.14
// := binds a name to a value (ref cell)
x := 42
x := x + 1 // rebinds — updates the same cell
// <- mutates memory at a location
buf := alloc(u8, 10)
buf[0] <- 99 // writes to heap memory
// : T = is a typed binding
count : i32 = 0
Memory Model
| Type | What it is | Managed by |
|---|---|---|
[*]T | Heap pointer | Perceus (RC) |
[]T | Slice (view) | Argus (scope) |
*T | Raw pointer | Argus (scope) |
[N; T] | Fixed array | Stack |
Perceus handles when to free heap memory. Argus ensures views don’t outlive their source. Both are compile-time — zero runtime overhead.
Multidimensional fixed arrays are written by nesting the element type: [rows; [cols; T]].
matrix : [2; [3; i32]] = .{
.{ 1, 2, 3 },
.{ 4, 5, 6 }
}
Effects
Console :: effect
fn print(msg: []const u8)
fn read_line() -> []u8
greet :: fn(name: []const u8) -> <Console> ()
Console.print("Hello, ")
Console.print(name)
Effects replace exceptions, IO, and mutable state with typed, composable handlers.