Map
โ†‘Zig

Zig comptime

Wiki conceptzigtype-systemmetaprogramming โ†ณ show in map Markdown
title
Zig comptime
type
concept
summary
Zig's compile-time evaluation mechanism โ€” same language at compile time as runtime, used for generics, typeclasses, and metaprogramming
parent
zig
tags
zig, type-system, metaprogramming
created
2026-04-30
updated
2026-04-30

comptime is Zig's mechanism for running ordinary Zig code at compile time. Function parameters, struct fields, and whole expressions can be marked comptime, and the compiler evaluates them while building the program. The key property is that compile-time code uses the same language and standard library as runtime code โ€” there is no separate template language and no preprocessor.

Because types are first-class values inside comptime, a comptime function that takes a type and returns a type is generics. A comptime function that takes a type and asserts it has certain methods (via @hasDecl) is a typeclass constraint. A comptime function that takes a type and returns a struct of wrapper methods is the typeclass dictionary itself.

Examples from a Haskell perspective

Newtype is a singleton struct:

struct PlayerHealth { health: u32 }

Sum types are tagged unions:

fn Maybe(comptime T: type) type {
    return union(enum) {
        value: T,
        nothing,
        ...
    };
}

Typeclasses are comptime functions that produce dictionaries. The author of zig-functional-programmers shows Eq(Point) returning a struct of eql/neq wrappers, with a @compileError if the type doesn't supply the underlying method. The dispatch is explicit (Point.Eq.eql(a, b)) โ€” the dictionary is a value you carry, not something the compiler inserts behind your back. That's mean-free-path-language in practice: less ergonomic, fewer surprises.

Why it matters

Comptime collapses several features that are usually distinct: generics, traits/typeclasses, macro systems, conditional compilation. There's one mechanism, and it's the same language you already know. For a Haskeller, the appeal is that you can do a lot of the type-system programming you'd reach for TypeFamilies or GADTs in Haskell with plain functions.