zig

Zig

Zig is what C should have been.

There. Said it. Now fuck off.


Been writing C since quite a while. Maybe before your parents met. Watched every attempt to “fix” C turn into a disaster. C++ became a monster. Go added a garbage collector like an idiot. Rust thinks it’s your mother.

Zig? Zig just fixed the broken parts.

No hidden allocations. You want memory? You ask for it. You pass an allocator.

var list = ArrayList(u32).init(allocator);
defer list.deinit();

See that defer? That’s how you free memory without forgetting. Not RAII. Not garbage collection. Just “do this when we’re done.” Revolutionary idea: saying what you mean.


Comptime is what macros wanted to be when they grew up. It’s just code. Runs at compile time. No preprocessor. No separate language. No debugging expanded macros until your eyes bleed.

fn fibonacci(comptime n: u32) u32 {
    return if (n <= 1) n else fibonacci(n - 1) + fibonacci(n - 2);
}

That runs during compilation. Not some template instantiation bullshit. Just runs.


Error handling without lies. No exceptions hiding in functions. No errno. Just:

const file = try std.fs.cwd().openFile("data.txt", .{});

See that try? That’s where it can fail. Right there. Visible. Like it should be.

C++ throws exceptions through seventeen layers of stack frames. Java pretends checked exceptions solved something. Go makes you write if err != nil until you want to die.

Zig just marks where things can fail. Novel concept.


Cross compilation that actually works.

zig build-exe hello.zig -target x86_64-windows

Done. No toolchain downloads. No Docker. No virtual machines. Build for ARM? Change the target. Build for WASM? Change the target.

Meanwhile, I spent three days last month trying to cross-compile C for ARM. Three days. For a 200-line program.


Kelley wrote a C compiler. From scratch. That actually works. He understands why C works. Most language designers don’t. They know why C is “bad” but not why it survived 50 years. Andrew knows both.


No headers. Let that sink in. No. Headers.

Import a module, get the module. Not textual inclusion from 1973. Not copy-pasting code with extra steps. Actual modules.

Forty years of #ifdef guards. Forty years of “did I include the right headers in the right order?” Gone.


C interop that doesn’t make me want to throw my keyboard:

const c = @cImport(@cInclude("stdio.h"));
_ = c.printf("It just works\n");

No binding generators. No FFI declarations. No wrapper libraries. Include the C header, call the C function. Done.


The build system is code. Not XML. Not YAML. Not Makefile tabs vs spaces. Code.

const exe = b.addExecutable("app", "src/main.zig");
exe.install();

Make is from 1976 and it shows. CMake is an abomination. Autotools should be tried for war crimes.

build.zig is just Zig code. I can debug it. I can understand it. I can fix it when it breaks.


Look, I’m not switching from C tomorrow. Got too much code. Too much muscle memory. Too much invested.

But when I start something new? Something that doesn’t need to link with decades of C libraries?

Yeah. I’ll use Zig.

It’s not perfect. Still version 0.something. APIs change. Documentation is… optimistic. But it’s honest. No magic. No lies. No “we know better than you.”

Just a language that lets me tell the computer what to do. Like C. But without the stupid parts.


Been programming for 2 decades. Seen languages come and go. Most are garbage. Some are tolerable.

Zig is good.


P.S. - Stage 2 compiler is self-hosted. Let that sink in.

P.P.S. - At least it’s not written in JavaScript.