Should Julia migrate from C to Zig? And Julia users that need C code with Julia?

Yes, Zig hasn’t hit 1.0, but is usable. Zig supports all platforms Julia supports (all Julia tier 1 platforms are also tier 1 in Zig).

  • Use Zig as a zero-dependency, drop-in C/C++ compiler that supports cross-compilation out-of-the-box. […]
  • Add a Zig compilation unit to C/C++ projects; cross-language LTO is enabled by default.

Zig is better at using C libraries than C is at using C libraries.

Zig is also a C compiler


Not only can Zig compile C code, but there is a very good reason to use Zig as a C compiler: Zig ships with libc.

Julia is just about to get rid of libm, and maybe libc is or isn’t problematic.

Another option would be Rust, and it also allows C inline with a crate. Rust is at 1.0+ and I believe already used in the Linux kernel. First step was for a driver, and I think approved recently.

I thought about posting this to internals (for Julia devs), or offtopic (for Julia users), but I think this is of interest to (some) users, and Julia (core) devs so maybe warranted here for exposure.

I think this was discussed (with porting to Rust if Im not mistaken).

There’s a lot to like about Zig vs. Rust, C and C++ (when you do not want garbage collection, or to implement a runtime/GC), even if you do not use Zig as a language, only its compiler and toolchain:

Zig is not just a programming language but also a toolchain that can help you maintain and gradually modernize existing C/C++ projects, based on your needs.

Rust has an advantage with no race conditions, but I think that’s more if your whole project is in Rust, and for Julia’s runtime doesn’t apply. [Of course we want no race conditions in Julia code, or the runtime though.]

No hidden allocations

Zig has a hands-off approach when it comes to heap allocation. There is no new keyword or any other language feature that uses a heap allocator (e.g. string concatenation operator[1]). The entire concept of the heap is managed by library and application code, not by the language.

Examples of hidden allocations:

  • Go’s defer allocates memory to a function-local stack. In addition to being an unintuitive way for this control flow to work, it can cause out-of-memory failures if you use defer inside a loop.
  • C++ coroutines allocate heap memory in order to call a coroutine.

First-class support for no standard library

As hinted above, Zig has an entirely optional standard library. Each std lib API only gets compiled into your program if you use it. Zig has equal support for either linking against libc or not linking against it. Zig is friendly to bare-metal and high-performance development.

It’s the best of both worlds; for example in Zig, WebAssembly programs can both use the normal features of the standard library, and still result in the tiniest binaries when compared to other programming languages that support compiling to WebAssembly.

A Portable Language for Libraries

One of the holy grails of programming is code reuse. Sadly, in practice, we find ourselves re-inventing the wheel many times over again. Often it’s justified.

  • If an application has real-time requirements, then any library that uses garbage collection or any other non-deterministic behavior is disqualified as a dependency. […]
  • Currently it is pragmatically true that C is the most versatile and portable language. Any language that does not have the ability to interact with C code risks obscurity. Zig is attempting to become the new portable language for libraries by simultaneously making it straightforward to conform to the C ABI for external functions, and introducing safety and language design that prevents common bugs within the implementations.

A Package Manager and Build System for Existing Projects

Zig is a programming language, but it also ships with a build system and package manager that are intended to be useful even in the context of a traditional C/C++ project.

Not only can you write Zig code instead of C or C++ code, but you can use Zig as a replacement for autotools, cmake, make, scons, ninja, etc

Obviously I’m not the dude to say anything about this matter, but I think core devs’ hands are full for the foreseeable future. Maybe in a few years when these languages are more stable and when people have more time, these codebase conversions can be looked at again.


Why would / should a Julian care about Zig?

If you simply use Julia (only) then not. Many use C code with though, and may have to maintain that code, so I found this interesting:

Zig is better at using C libraries than C is at using C libraries.

If you want to maintain such code (not just for hard-real time, another reason to use non-GC languages, or Julia without the GC), by migrating to a different language, then Julia is of course a very valid choice, at least in most cases. The point of Zig is though that the code (like C) will be more portable across languages (since no GC or runtime), and will “result in the tiniest binaries”.

1 Like

By migrate to Zig, I mean slowly, or not at all for old C code, just new code that would have been made in C. So there’s no need to port to Zig or Rust.

There’s no rush, understandable if people want to wait for Zig 1.0, but at least Rust is stable.