4 ms·
Zig is aiming to be lower level than Rust. As the project homepage prominently advertises, it has no hidden memory allocation or control flow. It also gives mor
by bunderbunder 7d ago
Zig is aiming to be lower level than Rust. As the project homepage prominently advertises, it has no hidden memory allocation or control flow. It also gives more control over how memory is allocated, which is potentially useful in applications with particularly tight performance requirements.
Kelley first created Zig when hr was working on a digital audio workstation and found most existing languages to be awkward for working with particularly hard real time requirements, but still wanted something more modern than C. Im speculating here, but I believe its advantage over Rust for that specific application is that you have tighter control over exactly when memory is allocated and deallocated, and how data is laid out in it. Rust wants to tie allocation lifetimes to scope in a very fine grained way that I would guess is beneficial the vast majority of the time, but does still make it harder to reason about when you’re about to stall out the CPU while the allocator does its thing.
- packetlost 7d ago> it has no hidden memory allocation or control flow Rust had like 3 allocating types total. If you aren't working with extremely deeply nested 3rd party types it's trivial to identify when allocations happen. Hell you could throw a lint rule together in like 5 minutes to warn on it if you're really worried. Besides Drop (excluding async) is there even any hidden control flow? > Im speculating here, but I believe its advantage over Rust for that specific application is that you have tighter control over exactly when memory is allocated and deallocated, and how data is laid out in it. Rust has almost exactly the same semantics for controlling allocations and deallocations, it just prevents you from screwing it up and not freeing something or using the allocation after freeing it. You still have to pass around your reference in your call stack until you no longer need it. > Rust wants to tie allocation lifetimes to scope in a very fine grained way that I would guess is beneficial the vast majority of the time, but does still make it harder to reason about when you’re about to stall out the CPU while the allocator does its thing. It's really not substantially different. You allocate ahead of time or don't allocate at all. The only real difference is you might want to use an Option instead of an uninitialized pointer because it's semantically more correct and harder to screw up.
- sennalen 7d agoI wish people would stop inventing new languages for nostd when we have nostd
- bunderbunder 7d agoBut here I feel like we’re at risk of heading down the same old doom spiral that plagues any conversation about programming languages when people try to treat it as a competition: getting pedantic about what’s technically possible in a language. It’s much more interesting to talk about how a language wants to be used. So, in the case of Zig, every function that wants to be able to allocate or deallocate heap memory needs an explicit reference to an allocator. That means that you can tell whether a function might allocate memory from its signature. It also means that changing a function so that it can allocate is explicitly a breaking change. That’s a really interesting design decision. And the reasons why someone would or would not want something like that baked directly into the language are so much more interesting than bickering about how technically with proper discipline you can have that kind of control in any non-GC language.
- orf 7d agoI agree with you, but it’s not baked directly into the language? It’s just a convention and a shared trait?
- ponkpanda 7d agoNot original commenter but the reality with zig is a little in between being simply convention vs. a language requirement. Is it a language requirement? no. However, there's no global allocator in zig. You simply cannot call the language's equivalent of malloc() because it doesn't exist - at least not as a global symbol. That leaves you with three choices: 1) Define a global allocator; is a valid choice and would make a zig program more like C, C++ or Rust in terms of not having to think about scope-level allocation patterns 2) Pass an allocator into that scope (this is the community convention) 3) Create/instantiate an allocator itself inside that scope (1) would be valid, though may not be idiomatic; global allocator like malloc becomes an opt-in (2) Expensive and inefficient for most scopes, though not all. (3) cheap, idiomatic but potential for noise/boilerplate
- kllrnohj 7d ago> Zig is aiming to be lower level than Rust. Zig and Rust are equivalently "low level". Zig isn't any closer to the hardware than Rust is. > but I believe its advantage over Rust for that specific application is that you have tighter control over exactly when memory is allocated and deallocated, and how data is laid out in it. Rust gives you all this, too. Zig's primary (possibly only) advantage over Rust is that it has much faster compilation times.