🎓 A1Learner
🔍
0 of 46 lessons completed

Zig Comptime Code Generation

Code generation is the creation of new code by a program while it is being compiled. In Zig, a comptime function can return a type, and each use of that function creates a fresh type.

Generating A Pair Type

This program builds a pair type for u32 values. It stores 3 and 4, then prints their sum.

const std = @import("std");
fn Pair(comptime T: type) type {
    return struct { a: T, b: T };
}
pub fn main() !void {
    const out = std.io.getStdOut().writer();
    const p = Pair(u32){ .a = 3, .b = 4 };
    try out.print("{}\n", .{p.a + p.b});
}

Generating A Function

This program builds an adder function that adds 5. It applies the new function to 10.

const std = @import("std");
fn makeAdder(comptime n: i32) fn (i32) i32 {
    return struct {
        fn f(x: i32) i32 {
            return x + n;
        }
    }.f;
}
pub fn main() !void {
    const out = std.io.getStdOut().writer();
    const add5 = makeAdder(5);
    try out.print("{}\n", .{add5(10)});
}

Generating Two Pair Types

This program builds pair types for two different value types. Each pair type holds its own kind of value.

const std = @import("std");
fn Pair(comptime T: type) type {
    return struct { a: T, b: T };
}
pub fn main() !void {
    const out = std.io.getStdOut().writer();
    const p = Pair(u32){ .a = 1, .b = 2 };
    const q = Pair(i32){ .a = 10, .b = 20 };
    try out.print("{} {}\n", .{ p.a + p.b, q.a + q.b });
}

Example

const std = @import("std");
fn Triple(comptime T: type) type {
    return struct { a: T, b: T, c: T };
}
pub fn main() !void {
    const out = std.io.getStdOut().writer();
    const t = Triple(i32){ .a = 1, .b = 2, .c = 3 };
    try out.print("{}\n", .{t.a + t.b + t.c});
}

Key points

  • Code generation: code generation is the creation of code at compile time from a comptime function.
  • A type function: a type function is a comptime function that returns a type.
  • Each call to a type function with different inputs can produce a different type.
  • A generated type can hold values of the type it was built from.
  • A comptime function can also return a function, so one definition can produce many small functions.
  • Generated code is checked like handwritten code, so mistakes are caught at compile time.

The type function builds a struct type with three fields of the same type. The main function builds the i32 version of that type and fills its fields. It then prints the sum of the three values.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

What does a comptime function that returns a type produce?