Generics & Interfaces
Declare a generic type with <T>; type arguments are inferred at use, so you rarely write them. Everything monomorphizes to Zig comptime generics — no runtime cost.
type Box<T> = { value: T }
fn Box<T>.get(self) -> T { return self.value }
fn Box<T>.replace(mut self, v: T) { self.value = v }
type Pair<A, B> = { first: A, second: B }Interfaces
An interface is a named set of methods (with Self), and a parameter can be constrained to one with <T: Iface> — checked structurally at instantiation (a type satisfies an interface just by having the methods).
interface Show {
fn show(self) -> string
}
type Point = { x: int, y: int }
fn Point.show(self) -> string { return "({self.x}, {self.y})" } # Point satisfies Show
# `T: Show` requires the argument to implement Show — a compile error otherwise.
type Labeled<T: Show> = { item: T }
fn Labeled<T: Show>.render(self) -> string {
return "[" + self.item.show() + "]" # dispatches through T → the concrete type
}
route GET "/demo" {
var b = Box { value: 41 } # Box<int>, inferred from the field
b.replace(b.get() + 1)
let p = Pair { first: "answer", second: 42 } # Pair<string, int>
let lbl = Labeled { item: Point { x: 3, y: 4 } } # a non-Show type is a compile error
respond "box={b.get()} pair={p.first}/{p.second} labeled={lbl.render()}"
}Dispatch through a type parameter
Methods lower to pub fns inside the (comptime-generic) struct, so calling a constrained interface method through a type parameter — key.hash() inside a HashMap<K: Key> — dispatches to the concrete type with no runtime cost.
Bidirectional inference
Type checking is bidirectional: an expected type flows into null, empty [] / [:], generic record literals, filled, and generic function calls, so empty generic containers and generic constructors infer their parameters from context.
Put together, examples/hashmap.weld is a fully generic HashMap<K: Key, V> written entirely in Weld — open addressing over any key type that implements hash / equals, with a generic constructor, monomorphized to Zig comptime generics. The built-in [K: V] map is a convenience, not a necessity.