Live data from Hacker News

Partially Matching Zig Enums

matklad.github.io

111–120 of 170 posts

Re: Partially Matching Zig Enums

#111
post #40

Earlier quoted context omitted.

I think the problem with this attitude is the compiler becomes a middle manager you have to appease rather than a collaborator. Certainly there are advantages to having a manager, but if you go off the beaten track with Rust, you will not have a good time. I write most of my code in Zig these days and I think being able to segfault is a small price to pay to never have to see `Arc >>` again.

Not to mention that `Arc` uses a GC (and not a stellar one, at that)...

Lol, what are you even trying to say here?

Is Zig such an amazing language that while using it you won't ever need reference-counted pointers?

Re: Partially Matching Zig Enums

#112
post #88

Earlier quoted context omitted.

> Then why do my data structures detect if I go out of bounds? I didn't mean you can't write C++ code that enforces that, I said C++ itself doesn't enforce it. > Yes. You can clean up memory allocations automatically with destructors and have value semantics for memory that is on the heap. Surely there are other ways to do that. E.g. Zig has defer. You can say that you may forget to write defer, which is true, but th…

Zig has defer. And C has free, but you have to remember to use it and use it correctly every single time instead of the memory working by default with no intervention. Says most people in the field of software correctness Not true, the last 30 years have had much safer languages than before java, scripting languages, modern C++ and rust. That's true, but these are not memory safety guarantees. Pragmatically they mean…

>C has free; zig has defer

But even in a c++ destructer if you forget to dealloc a private heap allocation ... then you're in the same darn place.

Re: Partially Matching Zig Enums

#114
post #7

This is one the reasons I find it so silly when people disregard Zig «because it’s just another memory unsafe language»: There’s plenty of innovation within Zig, especially related to comptime and metaprogramming. I really hope other languages are paying attention and steals some of these ideas. «inline else» is also very powerful tool to easily abstract away code with no runtime cost.

This isn’t intended as flamebait. I’m trying to understand Zig’s long-term positioning and design philosophy. I have serious confusion about the type of problems Zig is aiming to solve. In my view, Zig is not solving the actual hard problems in systems programming and it doesn't have the foundation to either.

Memory safety? Still entirely manual. Race conditions? Nothing in the language prevents them. There’s no ownership model, no lifetime analysis, no way to tie resource management to the type system. Compare that to Rust’s borrow checker or modern C++’s RAII and concepts. Zig’s type system is shallow. comptime is nice for generating code, but it doesn’t give you formal guarantees or expressive power for invariants, safety, or correctness.

The type system itself has no serious formal grounding. It can’t encode complex invariants, can’t track aliasing, can’t enforce concurrency safety and can’t model safe resource lifetimes. These aren’t academic extras — they’re exactly what decades of research in programming languages, operating systems and concurrent computing tell us you need to scale safety and correctness. Zig ignores them. Performance? When the policy is in the type (allocator choice, borrowing/ownership, fusion shape), Rust/C++ compilers can specialize, inline, and eliminate overhead. In Zig, the same policies are usually runtime values or conventions, which means more indirect calls, more defensive copies and fewer whole-program optimizations.

Concurrency is another major gap and in a real systems language, it cannot be an afterthought. Even if Zig isn’t currently aiming to solve concurrency or safety, a “serious” systems language inevitably has to, because these are the problems that determine scalability, maintainability and security over decades. The async model in Zig is little more than manual coroutine lowering: the compiler rewrites your function into a state machine and leaves correctness entirely to the programmer. There’s no structured concurrency, no safe cancellation, no prevention of shared-state hazards. Without a concurrency model that integrates into the type system, you can’t make guarantees about thread safety or race freedom and you end up relying entirely on discipline (which doesn’t scale).

Even in its most-touted features, Zig seems to be solving syntactic sugar problems, not the important systems problems. defer and errdefer? They’re effectively cleaner syntax for patterns C has had for decades through GNU’s __attribute__((cleanup)) or macro-based scope guards. Error unions? A nice alternative to out-parameters but just syntactic polish over an old idea. comptime? A more integrated macro system but still aimed at reducing boilerplate rather than providing deeper correctness guarantees.

The allocator interface? Another missed opportunity. Zig could have made it type-aware, preventing allocator misuse and catching entire classes of errors at compile time. Instead, it’s basically malloc/free with slightly cleaner function signatures. No safety net, no policy enforcement.

Zig discards decades of research in type systems, concurrency models, safety guarantees, and memory management, then reimplements C with a few ergonomic wins and leaves the hard problems untouched. It’s a restart without the research and not systems language evolution.

I am not a Rust fanatic but by contrast if you’re moving away from C++ or C, Rust actually tackles the big issues. It enforces memory safety without a garbage collector, prevents data races in safe code through its ownership and type system, offers structured concurrency with async/await and has been battle-tested in production for everything from browser engines to operating systems to databases. It is built on decades of progress and integrates those lessons into a language designed to scale correctness and performance together.

In my own code (primarily C++ and Rust), Zig wouldn’t solve a single core problem I face. Memory safety would still be my responsibility, concurrency would still be entirely manual, performance tuning would remain just as challenging and the type system wouldn’t catch the subtle bugs that matter most. The net result would be cosmetic changes paired with fewer correctness guarantees. Even C, for all its flaws, is better defined than Zig (both in having a detailed, standardized specification and in benefiting from partial formalization).

I am eager and optimistic that Zig starts taking itself seriously as a systems language. With new talent, deeper engagement with existing research and a focus on solving the actual hard problems, not just smoothing over C’s syntax, Zig could grow into something much more than it is today. But until then, the question remains: what problems is Zig actually solving that make it worth adopting over Rust or even modern C++? What concrete systems programming problems has Zig’s development team personally run into that shaped its design and are those really the most critical issues worth addressing in a new systems language?

If all it offers is nicer syntax over the same old pitfalls, I don’t see it and I don’t see why anyone betting on long-term systems software should.

Re: Partially Matching Zig Enums

#115
post #104
post #102

Earlier quoted context omitted.

Memory leaks are also a safety issue. Especially not running destructors can be a safety issue, but also a resource leak is at least a DoS. IIRC Rust also included not having memory leaks earlier in their definition of memory safety, but dropped it later.

The vast majority of catastrophic problems - nearly all of them, in the grand scheme of things - including those that can cause total system failure or theft of all data are not considered memory safety issues (which is one of the reasons that memory safety is overestimated or at least misunderstood, IMO, and why I prefer to talk about correctness in general). Memory safety refers to a specific kind of problems that…

Memory safety - as now being popularized by Rust in its current form - mostly corresponds to not having UB in C or C++. My point is that this not the only definition and not even the definition Rust started with.

Memory leaks are often a part of the definition of memory safety because otherwise it is trivial to fix use-after-free, i.e. simple never free the memory. Rust dropped this part because it was too hard. So in some sense the cheated a little bit.

Re: Partially Matching Zig Enums

#116
post #108

Earlier quoted context omitted.

Suppose I have a self-contained Zig project and it has a nasty memory safety bug - how can I identify where the cause might be? What parts of my project source are potentially unsafe ? You've said it's not everything, so, what's excluded? What can I rule out?

You can rule out a bounds violations from all but specifically marked unsafe code.

And then we forget about all other types of undefined behavior?

I would say that a cursory search on ”segfault” in the Bun repo tells a different story.

https://github.com/oven-sh/bun/issues?q=is%3Aissue%20state%3...

Re: Partially Matching Zig Enums

#117
post #108

Earlier quoted context omitted.

Suppose I have a self-contained Zig project and it has a nasty memory safety bug - how can I identify where the cause might be? What parts of my project source are potentially unsafe ? You've said it's not everything, so, what's excluded? What can I rule out?

You can rule out a bounds violations from all but specifically marked unsafe code.

The same useless claim could be made for C and with the same effect.

The trick Rust is doing here that Zig is not is that Rust's safe contracts are always what we would call wide contracts. As a safe Rust programmer it's never your fault because you were "holding it wrong". For example If you insist on sorting a Vec even though Foozles all claim they're greater even than themselves, Rust doesn't say (as C and C++ do) too bad, you broke it so now all bets are off, sorting won't be useful in Rust because Foozles don't have a coherent ordering, but your program is fine. In fact today it's quite fast to uselessly "sort" that container.

Zig has numerous narrow contracts, which means when you write Zig touching any of those contracts it is your responsibility as a Zig programmer to ensure all their requirements were upheld, and when you in turn create code or types you will likely find you add yet further narrowness - so you can be and in practice often are, "holding it wrong".

Re: Partially Matching Zig Enums

#118
post #108

Earlier quoted context omitted.

You can rule out a bounds violations from all but specifically marked unsafe code.

The same useless claim could be made for C and with the same effect. The trick Rust is doing here that Zig is not is that Rust's safe contracts are always what we would call wide contracts. As a safe Rust programmer it's never your fault because you were "holding it wrong". For example If you insist on sorting a Vec even though Foozles all claim they're greater even than themselves, Rust doesn't say (as C and C++ do)…

> The same useless claim could be made for C and with the same effect

It really can't be.

Memory safety is problematic because it's a common cause of some dangerous bugs. Of the two main kinds of memory safety, Rust generally eliminates both, leaving only unsafe Rust and foreign code as possible sites of memory unsafety. Zig, on the other hand, generally eliminates only the more dangerous kind, leaving only unsafe Zig and foreign code as possible sites of that.

Mind you, the vast majority of horrific, catastrophic bugs are not due to UAF. So if we get a horrific, catastrophic bug in Rust, we can eliminate UAF as a cause leaving us only with most possible causes, just as in most programming languages used to write most of the software in the world already.

This point of ha-ha, you also got a segfault while I only got all other bugs doesn't make sense from a software correctness perspective.

There is no binary line between Rust and Zig that makes Zig's superior safety to C that couldn't also be put between Rust and languages that make far stronger guarantees, putting Rust in the same bucket as C. If you think that the argument, "Rust, just like C, is unable to guarantee the vast majority of correctness properties that ATS can, therefore it is equally useless" is silly, then so is trying to put Zig and C in the same bucket.

If you believe that eliminating certain classes of bugs is important for correctness even when you don't eliminate most bugs, then I don't see how a language that eliminates the more dangerous class of the two that Rust eliminates is "just as useless" as a language that eliminates neither.

I have been programming in both C++ and Java for a very long time, and while I appreciate Java's safety, the main difference between the two languages for me hasn't been a different in correctness but in productivity. That productivity comes from Java's superior abstraction - I can make many different kinds of local changes without affecting other code at all, and that is not the case in a low-level language, be it C, C++, Zig, or Rust. I think it's good that Zig and Rust offer bounds ("spatial") safety. I also think it's good that Rust offers UAF ("temporal") safety, but I find the price of that too high for my liking.

Of course, my experience is not universal because I use C++ only for really low-level stuff (mostly when working on the HotSpot VM these days) where both Zig and Rust would have been used in their unsafe flavours anyway, because I'm more than happy to pay the increased memory footprint for higher productivity in other cases.

Re: Partially Matching Zig Enums

#119
post #109

Earlier quoted context omitted.

We keep talking about completely different things. If we're talking about "features that can help reduce some bug" then C++ or Rust have some that Zig doesn't and Zig has some that C++ or Rust don't. Which ends up more pragmatic is an empirical question that's hard to answer without data, but certainly focusing only on what C++ has and Zig doesn't while ignoring what Zig has that C++ doesn't is a strange way to compa…

We keep talking about completely different things. You said zig is safer than C++, then to make that argument you keep trying to redefine what safety means to include only features in the language syntax but not done in libraries while saying memory leaks don't matter and automatically freeing memory correctly doesn't matter.

I am not redefining what safety means. I am using the same definition of safety used in this entire thread by those debating the pros and cons of Rust being safer than Zig.

I definitely didn't say that memory leaks don't matter. They could possibly matter more than memory safety. They are just not called memory safety bugs, or code injection bugs, or off-by-one bugs. Memory safety is a name given to a class of bugs that lead to undefined behaviour in C or C++. It's not necessarily the most important class of bugs, but it is one, and when we're talking about preventing code injection or memory safety issues, we're not talking about preventing memory leaks - even if they're worse.

Now, if you want to talk about memory leaks and not memory safety (again, it's just a name given to some bugs and not others) then C, C++, Zig, and Rust, do not prevent them. Java prevents the kind "I forgot to free this object" kind, but not "I forgot about this object" kind.

Now, because unlike memory safety, none of these languages prevents memory leaks, it's really hard to say which of them leads to the fewest memory leaks. You really like C++'s destructors and find them useful, I really hate C++'s destructors and find them harmful, and we all have different opinions on why our way is better when it comes to memory leaks. What we don't have is data. So you can say having destructors helps and I can say no they don't until the end of time, but there's no way of knowing which is really better. So all we can do now, is to use the things we find useful to us without making broad generalisations about software correctness that we can't actually support with any evidence.

Re: Partially Matching Zig Enums

#120
post #115
post #104

Earlier quoted context omitted.

The vast majority of catastrophic problems - nearly all of them, in the grand scheme of things - including those that can cause total system failure or theft of all data are not considered memory safety issues (which is one of the reasons that memory safety is overestimated or at least misunderstood, IMO, and why I prefer to talk about correctness in general). Memory safety refers to a specific kind of problems that…

Memory safety - as now being popularized by Rust in its current form - mostly corresponds to not having UB in C or C++. My point is that this not the only definition and not even the definition Rust started with. Memory leaks are often a part of the definition of memory safety because otherwise it is trivial to fix use-after-free, i.e. simple never free the memory. Rust dropped this part because it was too hard. So i…

Well, when Rust came out I had only been programming in C and C++ for about 15, maybe 20 years, but I think that even then we generally used memory safety to refer to problems that can cause "type confusion". In any event, given that none of the languages mentioned here - C, C++, Zig, or Rust - prevent memory leaks, I don't think that the question of whether or not we include it under the umbrella of memory safety could offer insight on the interesting distinctions between these languages.
Post reply on HN