Advanced Features
Impl blocks
Section titled “Impl blocks”Methods attach to structs with self first:
struct Rectangle {width: int, height: int}
impl Rectangle { func area(self) -> int { return self.width * self.height } func perimeter(self) -> int { return (self.width + self.height) * 2 }}
rect := Rectangle{width: 3, height: 4}println(rect.area()) // 12println(rect.perimeter()) // 14Generics
Section titled “Generics”func min<T: Ord>(a: T, b: T) -> T { if a < b { a } else { b }}
println(min(3, 5)) // 3Bounds like Ord unlock comparisons; inference fills the parameters at each
call site. See Language Reference for the full rules.
Variants as control flow
Section titled “Variants as control flow”Option and Result compose with match, ?? and the unwrap_* family
instead of branching on nulls:
func find_name(id: int) -> Option<str> { if id == 1 { .some("Ada") } else { .none }}
match find_name(1) { .some(name) => println("Found: {name}"), .none => println("Unknown id"),}Closures over shared state
Section titled “Closures over shared state”mult := 3scaled := map(range(1, 6), |x: int| x * mult)println(scaled) // [3, 6, 9, 12, 15]Native builds
Section titled “Native builds”zz run type-checks and executes through the VM — ideal for iteration.
zz build emits a native binary instead:
zz build app.zz # dev binary next to the sourcezz build -p app.zz # optimized release binaryzz build --static app.zz # static binaryzz build --pgo app.zz # profile-guided buildBoth runtimes share the pure-ZZ standard library, so library code behaves identically either way.
Modules and imports
Section titled “Modules and imports”Imports resolve relative to the source file; std.* loads the built-ins:
import std.mathimport std.jsonimport utils.helperproject/├── main.zz└── utils/ └── helper.zz