7 February 2019
A little while ago, I start to play with a shiny new systems programming language called Zig. Pretty quickly, I was thrilled by it: it had a slew of interesting ideas that I enjoyed, and its syntax was nice to boot. The first thing I found really nice was
comptime means what it says: anything marked as comptime will either be known or calculated at compile time. If youre familiar with Jai, this is somewhat similar to
#run, but a little less powerful (if I understand correctly).
comptime can be used to mark variables, mark function arguments, or use it to set off a code block for more powerful computation. In a sense, this is metaprogramming in Zig, since there is no preprocessor or macros. And honestly, I love it. Back when I was writing an x86 kernel (which I quickly turned away from, because x86), I was able to instantiate both my GDT and IDT at compile time. Ill admit that this isnt a massive runtime performance boost, but it gives a good example of how powerful comptime is. Zig also does this, at first, seemingly peculiar approach to allocation: there is no default allocator. Any function that needs to allocate memory on the heap has to be given an allocator as a function argument. While the standard library does feature a number of different allocator types (you can use whichever one gives you the best performance, and its great for hosted code), that isnt even the best part. Using an allocator model like that means that the standard library can be used in freestanding code. You can create a temporary heap by making an array of u8, getting a slice of it (
array[0..]), and passing that to an allocator creator function to get a little heap of your own. Need to use a
HashMap in your freestanding aarch64 code? No problem! Make an allocator. It is, for me, the greatest thing Ive come across in quite some time. Also, man, is it easy to do systems programming in Zig. The language features some great things, like the
align(N) keyword, which lets you align a variable with ease. Or the
linksection(".section") keyword, which lets you put a function or variable in its own linksection. This any plenty of other functions and keywords make Zig a joy to write code in, and allow for writing really powerful code. Ill conclude my gushing with mention of the C interop. Zig has amazing C interop, that only keeps getting better. While it does have some limitations right now (for example, integers small than a
u32 cant be targeted for the C ABI), for most things it works wonderfully. Zigs creator, Andrew Kelly, has a youtube video where he ports some C++ Vulkan code to Zig, which to me just goes to show how well it works together. Ive moved a shocking amount of code from Rust to Zig over the last few days, which may be surprising to some: why would I move away from Rust, the mature-ish, safe, language of the future for a young language that doesnt have a godly borrow checker? Mainly, because Zig embodies what I love about programming: simple tools for the masterful craftsman to use for something amazing. If youre interested in Zig too, check out the links peppered throughout this entry for more.