4 ms·
Comptime is very nice but certainly more limited then Lisp. You can't generate arbitrary code with it. But good enough to implement something like JSON serializ
by ManBeardPc 1y ago
Comptime is very nice but certainly more limited then Lisp. You can't generate arbitrary code with it. But good enough to implement something like JSON serialization or Struct-of-Arrays in normal code that is readable.
Custom allocators are very nice. We are very much in manual memory management + optimization territory here. Having things like arena allocators makes a lot of difference in specific use-cases when you want/need every bit of performance. Also nice being able to switch the allocator for tests that is able to report leaks for example.
Yes, hidden control flow I mean something like exceptions, RAII or Rust's Dispose. So more a comparison to other languages than C.
The explanation I would refer to the talks "Don't forget to flush" or "Zig Roadmap 2026" from Andrew Kelley. Also the blog post "Zig's New Async I/O". I think it has something to do with being able to infer the required size of the stack, but already forgot the details.
https://kristoff.it/blog/zig-new-async-io/ https://kristoff.it/blog/zig-new-async-io/
https://youtu.be/f30PceqQWko?si=g2nLTE4ubWD14Zvn https://youtu.be/f30PceqQWko?si=g2nLTE4ubWD14Zvn
https://youtu.be/x3hOiOcbgeA?si=SUntYOYNOaxCRagc&t=3653 https://youtu.be/x3hOiOcbgeA?si=SUntYOYNOaxCRagc&t=3653
As to compared to Rust. The fast compile times are nice. Having a small language that you actually can understand helps to be productive. Not being restricted by the borrow checker makes it easier to implement some low-level things. Just being able to import most C code without wrapper makes the smaller ecosystem a much smaller problem. Rust is nice and certainly a good pick for many cases, but personally I often feel overwhelmed by the complexity and tons of tons of types for everything.
- rowanG077 1y agoRust dispose? I think you mean drop. But I don't see how that is hidden control flow. It's very clear when it drop is called.
- pron 1y agoIt's clear once you know that an object implements the Drop trait, but you can't see that at the use site, ergo it's hidden (same goes for C++ destructors). Zig wants every call to be visible. The tradeoff is between making sure you don't forget to write the cleanup call (Rust, C++) and making sure you don't forget to read the cleanup call (Zig). For low-level code I personally prefer Zig's tradeoff; others prefer the C++/Rust tradeoff.
- simonask 1y agoA funny thing I’ve noticed is that some Rust programmers will explicitly call `std::mem::drop(…)` in tricky situations where it really matters, like releasing a mutex with complex interactions - even at the end of scope. I kind of like it whenever a lock is held for more than a few lines. I think it’s a good compromise, because the consequences of forgetting it are way harsher. Memory leaks, deadlocks…
- pron 1y ago> I think it’s a good compromise, because the consequences of forgetting it are way harsher. And easier to detect. Knowing that no operation is carried out unless you can see it is important to many who do low-level programming. But there is no one right answer. Differences between programming languages, including those between Zig and Rust, are mostly about people's personal preferences because language designers rarely make choices that are universally inferior than others. When they differ, it's because both sides are reasonable and have their proponents.
- rowanG077 1y agoWhat do you mean if an object implements a drop? Whether an object implements a drop has no bearing on when it is called. I mean a developer can manually call it. But it is always clear when it is called.
- ManBeardPc 1y agoThe point is the code is on another type. Any variable could by of a type that implements some Drop logic. It is mostly called implicitly where it is used, wether you as a programmer are aware of it or not. You would need to check. In Zig you need to call everything explicitly, meaning in the function you need to call what you want to be executed, no other code will run. The decision if you want some cleanup logic is made at the point of usage, not by the type itself. That is the point of it, you look at a function and directly see what happens right there, not in other files/packages.
- 1y ago
- ManBeardPc 1y agoDrop yes. Thanks for the correction. It is clear when it is called, but you have to check in code you are not currently seeing as any type could implement it. May seem like a minor thing, but is not explicit at the point of usage. In Zig only code you call explicitly runs, meaning if there is no defer nothing happens at the end of the scope.
- taminka 1y ago> Yes, hidden control flow I mean something like exceptions, RAII or Rust's Dispose. So more a comparison to other languages than C. C has macros, which is the ultimate form of hidden control flow, where a symbol can expand to any arbitrary code... also hidden allocations and functions that can error, which you could argue isn't traditionally understood as hidden control flow, but it's still nice to know when stuff is allocated and/or can create an error