Types
Dogma is statically typed. All types are checked at compile time using Hindley-Milner inference — you rarely need to annotate explicitly.
Primitives🔗
| Type | Description | Literal example |
|---|---|---|
i32 | 32-bit signed integer | 42 |
i64 | 64-bit signed integer | 9999999999 |
f32 | 32-bit float | 3.14 |
f64 | 64-bit float | 3.14159265 |
bool | Boolean | true, false |
String | UTF-8 string | "hello" |
() | Unit — no value | Return type of fn main() |
Arrays🔗
let numbers: [i32] = [1, 2, 3, 4, 5]
let first = numbers[0] // i32
let length: i32 = numbers.len()
Arrays are immutable by default. Use push/pop from dogma:core to create new arrays. arr.len() returns i32 — use i32 for loop counters over arrays.
Structs🔗
struct Player {
name: String,
health: i32,
}
impl Player {
fn is_alive(self) -> bool {
self.health > 0
}
}
fn main() {
let p = Player { name: "Aria", health: 100 }
if p.is_alive() { println("Alive!") }
}
Enums🔗
enum Direction {
North,
South,
East,
West,
}
enum Shape {
Circle(f64),
Rectangle(f64, f64),
}
fn area(s: Shape) -> f64 {
match s {
Shape::Circle(r) => 3.14159 * r * r,
Shape::Rectangle(w, h) => w * h,
}
}
Option<T>🔗
Represents a value that may or may not be present.
fn find(items: [String], target: String) -> Option<i32> {
let mut i: i32 = 0
while i < items.len() {
if items[i] == target { return Some(i) }
i = i + 1
}
None
}
match find(["a", "b", "c"], "b") {
Some(idx) => println(f"Found at {idx}"),
None => println("Not found"),
}
Result<T, E>🔗
Represents success (Ok) or failure (Err).
fn divide(a: i32, b: i32) -> Result<i32, String> {
if b == 0 { Err("division by zero") }
else { Ok(a / b) }
}
Use the ? operator to propagate errors — see Error Handling.
Generics🔗
fn first<T>(items: [T]) -> Option<T> {
if items.len() == 0 { None }
else { Some(items[0]) }
}
What is not implemented🔗
pub/visibility modifiers, trait bounds (T: Display), dyn Trait, operator overloading, macros, async/await, JIT/AOT.