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

I'm not convinced that on average Zig is any less safe, or produces software that is any less stable, then Rust.

Zig embraces reality in its design. Allocation exist, hardware exists, our entire modern infrastructure is built on C. When you start to work directly with those things, there is going to be safety issues. That's just how it is. Zig tries to give you as many tools as possible to make good decisions at every turn, and help you catch mistakes. Like it's testing allocator detecting memory leaks.

Rust puts you in a box, where the outside world doesn't exist. As long as you play by its rules everything will be fine. But it eventually has to deal with this stuff, so it has unsafe. I suspect if Rust programmers went digging through all their dependencies, especially when they are working on low level stuff, they would be surprised by how much of it actually exists.

Zig tried to be more safe on average and make developers aware if pitfalls. Rust tried to be 100% safe where it can, and then not safe at all where it can't. Obviously Rusts approach has worked for it, but I don't think that invalidates Zigs. Especially when you start to get into projects where a lot of unsafe operations are needed.

Zig also has an advantage in that it simplifies memory management through its use of allocators. If you read Richard Feldman's write up on the Roc compilers rewtire in Zig, he talks about how he realized their memory allocation patterns were simple enough in Zig that they just didn't need the complexity of Rust.



To be clear, Rust encourages the development of safe abstractions around unsafe code, so that the concern goes from proportion of unsafe to encapsulation of unsafe. Whether you trust some library author to encapsulate their unsafe is, I think, reducible to whether you trust a library author to write a good library. Unsafe is not all-or-nothing. Thus, as with all languages, good general programming practices come before language features.


That's kind of my point. Because it's isolated and abstracted I wouldn't be surprised if most Rust devs have no idea how much unsafe code is actually out there.

Rust does not want you to think about memory management. You play by its rules and let it worry about allocations/deallocation. Frankly in that regard Rust has more in common with GC languages than it does Zig or C. Zig chooses to give the developer full control and provides tools to make writing correct/safe code easier.


Although not a comprehensive report, people tend to count the source lines of unsafe in a Rust codebase as a metric. Moreover, reputable libraries worth using typically take care to reduce unsafe, and where it is used, encapsulate it well. I don't think you have a substantive point on the matter. Unsafe certainly can be abused, but it's not a bogeyman that people scarcely catch glimpses of. Unsafe doesn't demote the safety of Rust to that of C, or something like that.

Your comments on Rust's philosophy towards memory management are off base. Rust is unlike GC languages, even Swift, in that it makes allocations and deallocations explicit. For example, I know that one approach to implementing async functions in trait objects was rejected because it would've made implicit heap allocations. Granted, Rust is far behind on reified and custom allocators. Rust has functionality to avoid the default alloc crate, which is the part of libstd that does heap allocations, and a library ecosystem for alternate data structures. Rust doesn't immediately give you total access, but it's only a few steps away. Could it be easier to work with? Absolutely. The same goes for unsafe.


Thank you for the thoughtful reply, but I think you missed my point.

I'm not saying Rust isn't substantially safer than C. When people like Greg Kroah-Hartman say that Rust by its design eliminates a lot of the memory bugs he's been fighting for 40 years, I believe him.

My point is that people tend to talk about it as an all or nothing proposition. That Rust is memory safe. Period. And any language that can't put that on the tin is immediately disqualified, that somehow their approach to solving similar problems is invalid.

By the very nature of the system no language that wants to interact with the hardware can be entirely memory safe, not even Rust. It has chosen a specific solution, and a pretty damn interesting one as far as that goes, but it still has to deal with unsafe. And the more directly your program has to deal with the hardware the more unsafe code it's going to have to deal with.

Zig has also chosen an approach to deal with the problem. Their's is one that gives far more direct control to the programmer. Every single memory allocation is explicit in that you have to directly interact with an allocator and you have to free that memory. It's not hidden behind constructors/destructors and controlled via RAII patterns (side note, there are managed data structures that you give an allocator to via an init and free via a deinit, but you still have to pass in the allocator and those are being largely replaced).

If you are only dealing with problems where you can interact with Rust's abstractions I'm sure it is more safe then Zig, but I don't think it's as big a difference as people think. And when you start digging down into systems level programming where the amount of unsafe code you have to write grows, Rusts advantage starts to diminish significantly.

To my point about Rust not wanting you to think about memory, take Vector as an example. You and I know that's doing heap allocations, but I guarantee you a not insignificant number of Rust devs just don't even think about it. And they certainly don't think about all the allocations/deallocations that have to happen to grow and shrink it dynamically.

Compare that to Zigs ArrayList. When you create it you have to explicitly hand it an allocator you created. It could be a general purpose allocator, but it could just as easily be an arena allocator, or even an allocator backed by a buffer you pre-allocated specifically for it. As the programmer you have to directly deal with the fact that thing allocats and deallocates.

Thats what I mean when I say Rust has more in common with GC languages in some ways. When I type "new" in Java I know I'm heap allocating a new object, just Java doesn't want me to think about that because the GC will deal with it. When you create a vector in Rust, it doesn't want you to think about the memory, it just wants you to follow it's borrow checker rules. Which is very different then thinking about allocation/deallocation patterns.


Thank you for your insights. I think this comes down to a culture problem. Some people such as myself obsess over the low-level details, so every usage of Vec stands out immediately. At the same time, many people like to use Rust in areas where heap allocations and the like aren't as significant, where GC languages would typically be used too. Discussions of memory safe languages are flawed, as you point out, though I feel like Rust is just the poster child and not a unique instance. What I take away from Rust's philosophy usually comes from the Rust team who develop the language, and I find them to generally be levelheaded when it comes to discussing Rust's merits and drawbacks. I do think Rust is a highly promising language, for which its team tirelessly addresses its major flaws[0], but it doesn't excuse hype-induced bias.

[0] I can't say it'll ever compile as fast as, say, Go, but all the work on compile times is impressive


I think that's honestly been a success for Rust nobody really talks about. It's enabled people who would never write in a non-garbage collected language to do just that.

Between the borrow checker and Cargo, it's brought system engineering to a whole group of people that never would have touched it before. People who don't want to deal with memory management can write code that doesn't require a GC. And they can easily pull in dependency for things they don't want to write.


I can attest to that. I had tried learning C++ previously, but getting started as a beginner is a bit of a nightmare (maybe that's because I was using Linux, so I couldn't use Visual Studio, but there's still a ton of complexity).

I was able to work through the Rust book though, and that was a great way to ease into the more difficult parts of systems programming.

I'm not contributing to a C project, but I feel a lot more comfortable since Rust caught all my early dumb mistakes, so I've learned to avoid the things that would shoot me in the foot.




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

Search: