3 ms·
> In all these things, what impressed me most was Zig’s approach to safety when working with the metal. Not in terms of an on/off decision, but as a spectrum. N
by scuff3d 1y ago
> In all these things, what impressed me most was Zig’s approach to safety when working with the metal. Not in terms of an on/off decision, but as a spectrum. Not aiming for 100% guarantees across 1 or 2 categories, but 90% and then across more categories. Not eliminating classes of bugs, but downgrading their probability. All while preserving the power-to-weight ratio of the language, to keep the language beautifully simple. - From TigerBeetles blog on this
Such an excellent summary. I've been trying to communicate this regarding the difference in Rust and Zigs approach to memory safety, and Joran does it so much better than I ever could.
- wocram 1y agoWhy is 90% enough?
- CitrusFruits 1y agoI think the idea is that perfect is the enemy of good here and that getting from 90% to 100% involves tradeoffs that aren't actually worth it from a language ergonomics point of view.
- bsder 1y agoWhat are you trading off to get from 90% to 100%? How about compile speed? Are you willing to wait an extra second to get 100%? How about 10 seconds? A minute? 10 Minutes? An hour? Rust is notoriously slow at compiling and people have been banging on it for a while. At some point, you have to accept that the language, itself, has properties that make compilation slow.
- kristianp 1y agoRust packages tend to have large dependency graphs which doesn't help the compile times. I've read the serde is a bit of a hog in that respect, for example. The rust philosophy is for a large language and large library too.
- matesz 1y agoI highly recommend checking out makepad [1] - they have +100k of rust code and the compile time is around 10-15 seconds on commodity hardware. However they are obsessed about performance. They reason for such speedy compile times, like you say, is that makepad has almost no external dependencies. [1] https://github.com/makepad/makepad/ https://github.com/makepad/makepad/
- scuff3d 1y agoI don't think you understand what he saying. Rust is 100% memory safe in specific places yes, but much less so when you have to dip into unsafe Rust. Unsafe memory access will always exist, you can't do anything about it. If you need to interact with the underlying system it's just something you have to deal with it. Zig on the other hand isn't 100% safe in any one part, but it's 90% safe in nearly all parts. Zig recognizes the outside world exists, and makes it easy to write safe correct code given that reality. Time will tell, but on average I suspect Zig and Rust will produce equally safe and correct software. The further away you get from the hardware the bigger Rust's advantage is, the closer you get to the hardware Zig has the edge.
- neckbeards 1y agoHow is Zig considered “90% safe”? It relies on manual memory management, its simple type system provides limited compile-time guarantees and it lacks a mature concurrency model (making safe parallelism difficult). Given these gaps, I struggle to see how Zig achieves a consistently high level of safety. It seems no safer than using AddressSanitizer at best?
- scuff3d 1y agoZig makes a lot of small choices that pile up to push you towards safety/correctness in your code. No hidden allocations is a big one. If something allocates you have to explicitly give it an allocator. This makes tracking allocations much simpler. Combined with the test allocator you can also detect memory leaks. Allocators also simplify memory management patterns. For example, it's trivially ease to use an arena. Then all your little allocations can be freed all at once, eliminating the need to track each individual allocation/free. The defer keyword allows you to place the free call near the allocation (same with other resources that require closing). This isn't always possible of course, but it is a lot of the time and makes it easier to track. Bounds checking is another big one. While loops/for loops with capture groups means you'll basically always see Zig programs iterating through arrays/slices in a manner that ensures you can't go out of bounds. In terms of general correctness you have explicit nullability. If something can be null you have to mark it as such directly in the type. Then when accessing it you have to unwrap it and deal with the null case. Same for errors. If something can return an error it's indicated in the return type. The error has to be unwrapped and then thanks to tagged unions you have to deal with all the different possible cases. There are language conviences like the try keyword that let you side step some of the explicit handling, but even those are easy to track. And you know you're doing something that might bite you. All of that adds up with a dozen other design choices to produce a language that makes it a lot easier to produce correct code. Edit: In terms of concurrency I have to give you that one. The language is still pre 1.0 so we'll have to see what happens.