💾 Archived View for tilde.pink › ~kaction › log › 2022-09-09.1.gmi captured on 2023-06-14 at 14:28:34. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
I heard about Zig programming language before, and was quite dismissive about it as "yet another C replacement". Short-sighted of me.
Couple days ago I stumbled upon it again, and decided to at least glance at documentation. Folks, it is really awesome. I am excited. Go read documentation yourself.
The most awesome feature is ability to execute code at compile time, and have this compile-time code access to all functions that will also be used at runtime. Power of Lisp macros or Template Haskell in C. In particular, this power allows implementing "printf" better than in C.
In C, format string argument to "printf", while 99% of time is literal, is treated no different than any other "const char *" argument to any other function, so format string is parsed at runtime and code that handles something obscure, like %A, is compiled in no matter whether you use it or not. Also, vardaic functions in C are very easy to misuse and pass argument type mismatching format string.
To avoid all these problems, another approach pionered (afaik) by DJB exists. Instead of kitchen-sink "printf" function we make dozen functions like "fmt_long", "fmt_float", "fmt_hex" and so on. That works well, but is annoyingly verbose.
In zig, "printf" examines format string at compile time, so type mismatch is now compile error and formatting code not needed is not compiled in. Best of two world.
Another great feature is distinction between nullable and non-nullable pointers and compiler enforcing that nullable pointer is checked for "null" before being dereferenced. Zig forces you to write equivalent of good C code, while compiling into the same instructions.
Yet another cool feature is concept of checked undefined behaviour. Undefined behaviour is necessary sacrifice on the altar of the performance, but Zig does it cleaner. Undefined behaviour prints backtrace and terminates program in Debug build. That simple. Oh, and Debug is the default build mode.
And all these shiny features compile into to static libraries (or dynamic, if you like) that contain functions with normal C ABI. Unless you care about portability, I see no reason to write C since now I can write Zig.