Owned values, explicit types, no GC. A language that reads clean and runs like C.
Zmeu is a typed systems language with an owned-value memory model and a low-ceremony, indentation-based surface. It lowers through an MLIR pipeline to the same LLVM IR shape as equivalent C — ownership, borrows, and effects checked up front, so invalid programs never reach the backend.
git clone https://github.com/yxanul/zmeu Less to write. Nothing given up.
A sum type and an exhaustive match. Zmeu proves every case is handled and
drops the ceremony; C makes you hand-roll a tag and write a default you
can forget.
enum Shape:
case Circle(radius: f64)
case Rect(side: f64)
def area(shape: Shape) -> f64:
return match shape:
case Circle(r) => 3.14159 * r * r
case Rect(s) => s * s typedef enum { CIRCLE, RECT } Tag;
typedef struct { Tag tag; double v; } Shape;
double area(Shape s) {
switch (s.tag) {
case CIRCLE: return 3.14159 * s.v * s.v;
case RECT: return s.v * s.v;
}
return 0.0; /* unreachable, still required */
} C-class performance,
with the receipts.
rustc on the large majority.
zmeu, C and Rust built -O3 -march=native on LLVM 22;
hyperfine, 40 runs, identical output verified.
Reproduce with benchmarks/run.sh.
option_unwrapsum-type unwrap 0.75× bitwise_castsinteger bit ops + casts 0.83× recursionrecursive calls, hot loop 0.89× generic_identitymonomorphised generic 0.99× result_trytry-propagation 1.00× struct_fieldsvalue-struct access 1.01× nested_array_sumclang autovectorises; ties Rust 1.22× The same machine code as C — and CI won't let it drift.
Result, Optional, generics and try lower to the
same LLVM IR shape as equivalent C — no hidden boxing, no dispatch, no allocation.
Every pull request re-counts the emitted IR against a declared threshold per case.
An optimisation regression blocks the merge, so “zero-cost” is a test, not a hope.
case panic oob alloca result_try 0 0 0 generic_identity 0 0 0 option_unwrap 0 0 0
Owned by default. Borrowed on purpose.
Single ownership, deterministic drop
Every value has one owner. Destructors run on scope exit — no GC, no reference counting, no runtime tax.
view and mut view borrows
Share without copying. Aliasing and lifetimes are checked before any code is generated; there is no unsafe escape hatch over the type system.
Proven at CFG MIR, before lowering
The front end's borrow and effect checker rejects invalid programs. Soundness never rides on an LLVM pass.
def sum(xs: view [i32]) -> i32:
var total = 0
for x in xs:
# yes, total += x is on the way — longhand for now :)
total = total + x
return total
def main() -> i32:
let nums: [i32; 4] = [3, 8, 11, 20]
return sum(view nums)