Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Zig is (or will be) memory-safe -- selectively. It just achieves that in a way that's very different from Rust. The way Zig helps you write memory safe programs is by adding runtime checks that eliminate undefined behaviour. UB becomes a panic. However, in your production build, you can choose to selectively remove those checks from some or all of your subroutines.

If you remove those checks, while Zig does not give you a sound guarantee there will be no undefined behaviour in production, it makes testing easier and faster, helping correctness across the board. After all, the goal is not to write your program in a language with some guarantees, but to produce a program with as few bugs -- undefined behaviour or others -- as cheaply as possible. Which approach results in safer, more correct programs, Rust's or Zig's? Only empirical study will tell.



Rust will be safer.

Reasoning is pretty simple: a dynamic approach (Zig) will only catch the memory errors for the tested code paths. This is probably only marginally better than running your C++ code's test suite with address sanitizer.

Rust's static approach provides memory safety for all code paths.


Your conclusion rests on the assumption that Rust's sound guarantees are free and have no cost to correctness while they might very well do, or, put differently, that "all else is equal." It's like concluding that you must be richer than me because you have more cash in your wallet. See my comment here for more: https://news.ycombinator.com/item?id=24617127


Yes, I am assuming that Rust isn't much harder to code in than Zig. Rust isn't that hard, really.

Since your point doesn't really have to do with which languages are involved (only that they are different somehow), one could similarly say that C might produce more correct programs than Rust or Zig for the same amount of effort.

New languages like Zig need to have a better story around safety than "only empirical observation will tell," because Rust's safety story is pretty compelling.


> Yes, I am assuming that Rust isn't much harder to code in than Zig. Rust isn't that hard, really.

You're assuming much more. The costs I mentioned are not about being harder to code. C++ is also easy to code in.

> one could similarly say that C might produce more correct programs than Rust or Zig for the same amount of effort.

True, and right now it might very well be. C has exceptional verification tools, which is why a lot of safety-critical software is not written in either C++ or Rust, but in C, Ada, and some domain-specific languages that compile to C like SCADE. But assuming "all external tools being equal" I would guess both Rust and Zig would be better, because they both have a very strong focus on correctness and do something about it, while C doesn't even try.

> because Rust's safety story is pretty compelling.

Zig has an exceptionally compelling safety story as well. It focuses on safety no less than Rust, but it does so in a different way. My personal guess would be that Zig's approach to correctness is at least as good as Rust if not more so, though I could be wrong, and I have no problem with people guessing the other way. After spending years with formal verification and following software correctness research, my only conclusion is that we don't have anywhere near a good model for software correctness that would allow us to make any reasonable projection about approaches.

The story, though, isn't just about correctness, and languages can be compelling in other ways, too. Language preference is largely based on personal aesthetics, and aesthetically Zig and Rust are very different. Rust's aesthetics are not to my liking but Zig's are, just as I'm sure the opposite is true for others. I see no reason why there should only be one aesthetic approach in low-level programming just as there isn't one approach in high-level programming.

So not expecting any resolution on the correctness approach any time yet, I think those two languages would appeal to different people.


Not a Zig user, but this seems to indicate Zig still doesn't always detect use-after-free even with all safety flags on. It seems progress is being made though. https://github.com/ziglang/zig/issues/3180


You are correct, that's still a WIP, but the goal is to have "safe Zig" (i.e. Zig with safety checks on) catch all undefined behaviour modulo explicitly marked unsafe casts (which correspond to unsafe Rust code).


That sounds great as long as the performance cost is not too high.


By "catch", do you mean at compile time?


Some at compile-time, and some at runtime.


More than that, people don't understand 'right tool for the job'.

For not-so-reliability-critical pieces of software, eg game related, zig might be easier to get it done. Some people are really passionate about rust and very talented, they aren't affected by rust's non-zero cognitive overhead. But us trivial 1x programmers are.


Even for the most safety-critical software Zig might be easier to get it done. Or maybe not -- nobody knows. As someone who once worked on safety-critical software, the system could kill people if a computation took too long or gave a wrong answer exactly as much as due to undefined behaviour. Is it better to eliminate undefined behaviour at the cost of making other kinds of testing more difficult? Hard to say.

Rust's approach is based on one guess re correctness, Zig's on another. My personal guess is that Zig's approach is ultimately more effective at reaching correctness, but I could be wrong. There's no way to know which is better by thinking about it -- correctness is just too complex a subject.


Readabity is also critical for correctness in human systems. If you get lost and expend too much mental energy fighting the borrow checker, you might miss other errors. You might get overconfident that your code is checked and miss a logic bug by not covering a case in your unit tests. You are writing unit tests, right?


> the goal is not to write your program in a language with some guarantees

How is that not the goal? The more bugs I can statically guarantee are absent the better!


> How is that not the goal?

The goal is to produce a program with as few serious bugs as possible, as cheaply as possible. It is never a goal to use a programming language with certain properties; that could just be a means to that end.

> The more bugs I can statically guarantee are absent the better!

Only provided that those guarantees don't come at a cost that could make finding the bugs you don't statically eliminate harder. How could it make it harder? By making the language overall harder to understand -- both by informal and formal analysis -- making safe evolution more tricky, and by slowing down compilation, which slows down the testing cycle and reducing the number of tests you write.

Correctness is a very complex subject, and that "the more sound guarantees the better" is not a consensus opinion on how to get there. For example, even in formal verification circles, a lot of current research focuses on reducing soundness (e.g. concolic testing vs. model-checking/deductive proofs). It's like the question of how to catch more fish: is a smaller net with small holes that guarantees no fish can get through it better, or is it better to cast a wider net with larger holes, that might let some fish slip through but covers a wider area?

Perhaps in the case of the net and the fish an answer could be given ahead of time if you know everything there is to know about the distribution of the fish size and their dispersion, but that's not the case with software bugs. We simply don't know enough, and the only way to answer the question is through empirical observation, over a wide range of applications and over a long time. It's also possible that both approaches are equally good at achieving correctness, and then it's just a matter of personal preference based on other aspects of the language.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: