The Zig Programing Language is a cool idea


Home | Blogs

This blog was written on Zig version 0.10.1, and some information is subject to change.

Zig is a programming language that tries to be even lower level than C but tries to be easier. The goals are to have no hidden control flow, no hidden memory allocations, no preprocessor, and no macros.

They have no hidden control, as they don't do anything more than you tell them to do. With most C compilers, they will include some code that runs before your code. Zig tries not to do this and only runs what is needed to run. This makes executables extremely small. Building with release-fast because we don't care about security, a Hello World program outputs a 692 kB file. That might not sound amazing, but we can strip the file, and then it becomes 88 kB. This still might not sound impressive. Hello World in C outputs a 16 kB file. The impressive thing about zig is that it uses no system libraries by default, not even libc. C requires libc on the host computer, but this still might not sound important as every system is going to have libc installed on it. Have you ever written a program and tried to use it on an old Debian system, and then you got five errors saying that some library was out of date and you couldn't run your program?

No hidden memory allocations is a nice feature, as memory allocations that happen in the background can be hard to work with. When you want performance and want to optimize something, you want to be able to edit everything, so something happening when you don't want it can be very annoying. If memory allocation is done in the background, it is hard for the compiler to know what the use case is and how to optimize for this unknown use case. This leads to a slower program and less control from you.

No processor or macro can be both good and bad. It's good because you know that the code you wrote is the only code that the compiler is getting. It won't try and do anything more than you or a library tell it specifically, and it will make it easier for you to manage everything as everything will have the same syntax as the language. Macros can be very helpful if you need to write some code multiple times but only want to do it once. This can be very helpful when you want to write multipul functions with multipul types but you only want to write the function once. Macros and preprocessors do make the program take longer to compile, and it can be hard for someone to read them as they can have different syntax from the rest of the programming language.

One big thing about Zig that I did not mention is that they try to make it so that you can link to any C library, first-class. These could be system libraries or even local libraries that get backed into the program. You can view an example of using the raylib library in Zig without doing any hard work here. They do say at the top that you have to build the program with extra flags, but you can put these in the build.zig file so people won't have to do that.

This all sounds amazing; what is the catch? For the record, I am no Zig god and only tried making some programs yesterday. My first impressions are that it is missing some things you expect from new languages now a days and would put it on the list of best programming languages. They have website documentation, but they only have the guide for the latest dev build and not the latest release build, so it can be hard when you try and link to a standard library function that does not exist. This documentation generator can't be run on your project (at least not through the official zig cli program), so you can't build some doc pages. As of now (that might be coming in v0.11.0), there is no package manager in zig. This is not a huge deal to me as you can always just use a git submodule to link to a library, but because some libraries keep up to date with the development zig and some with the stable zig, you can't really use git submodules. Zig is not at version 1.0 yet, so the standard library changes and some things that used to be allowed don't anymore, and vice versa. That means that you most likely won't be able to use a git submodule, as you will have to specify and tag or commit to set the head to.