(no title)
soyyo | 1 year ago
My understanting is that everyone is suggesting to move to memory safe languages when possible, however Zig does not seem to have any.
Since zig is a new language my guess is that the main use would be brand new projects, but sholdn't this be done in a memory safe language?
It seems that the selling point of Zig is: more modern than C but simpler than Rust, so I understand the appeal, but isn't this undermined by the lack of memory safety?
klabb3|1 year ago
Memory safety is a useful concept, but it’s not a panacea and it’s not binary. If the end goal was safety JS would have been fine. Safe rust is guaranteed memory safe which is a huge improvement for system programming but not necessarily the end-all-be-all. There are always tradeoffs depending on the application. I personally think having safety be easily achievable is more important than guaranteed. The problems we’ve had with C and C++ is that it’s been hard to achieve safety.
audunw|1 year ago
I think it remains to be seen if Zig is less safe than Rust in practice. In either case you have to write a lot of tests if you actually want your program to be safe. Rust doesn’t magically eliminate every possible bug. And if you’re running a good amount of tests in debug mode in Zig you’ll probably catch most memory safety bugs.
Still, if I was making something like a web browser I would probably use Rust
kibwen|1 year ago
This is a common misconception, but the `unsafe` keyword in Rust does not disable any of the features that enforce memory safety, rather it just unlocks the ability to perform a small number of new operations whose safety invariants must be manually upheld. Even codebases that have good reason to use `unsafe` in many places still extensively benefit from Rust's memory safety enforcement features.
flumpcakes|1 year ago
Zig is also a good choice if you care about safety - it simplifies things (by having a defer statement) and it's tooling is geared towards safety by having multiple targets that let you run your program in ways to catch memory safety issues during development. It is not enforced by the compiler, only at runtime in development/non-release-fast builds but still an improvement over C/C++.
int_19h|1 year ago
wavemode|1 year ago
Safety is a spectrum - C is less safe than C++, which is less safe than Zig, which is less safe than Rust, which is less safe than Java, which is less safe than Python. Undefined behavior and memory corruption are still possible in all of them, it's just a question of how easy it is to make it happen.
pkolaczk|1 year ago
jmull|1 year ago
IMO, partially. But zig isn't done, so we probably can't judge that yet.
Now, zig does have good memory safety. It's not at the level of Javascript or Rust, but it's not like C either.
Last I checked -- a while ago now -- user-after-free was a major issue in zig. IMO, that has to be addressed or zig really has no future.
Javascript really is a memory safe language. But its runtime and level of abstraction doesn't work for "systems programming".
For systems programming, I think you want (1) memory safety by default with escape hatches; and (2) a "low" level of abstraction -- basically one step above the virtual PDP-11 that compilers and CPUs have generally agreed on to target. That's to let the programmer think in terms of the execution model the CPU supports without dealing with all the details. And as a kind of addendum to (2), it needs to interop with C really well.
Rust has (1) nailed, I think. (2) is where it's weak. The low level is in there, but buried under piles of language feature complexity. Also, it disallows some perfectly safe memory management patterns, so you either need to reach for unsafe too often, or spend time contorting the code to suit the solution space (rather than spending time productively, on the problem space).
Zig is weak on (1). It has some good features, but also some big gaps. It's quite strong on (2) though.
My hope for zig -- don't know if it will happen or not -- is that it provides memory safety by default, but in a significantly more flexible way than rust, and maintains it's excellent characteristics for (2).
cweld510|1 year ago
C feels substantially different than Rust. It’s much smaller and less complicated. It’s technically statically typed, but also not in that it doesn’t really have robust non-primitive types. It’s a very flexible language and really good for problems where you really do have to read and write to random memory locations, rearrange registers, use raw function pointers, that sort of thing. Writing C to me feels a lot closer to Python sometimes than to Rust or C++. Writing algorithms can be easier because there is less to get in your way. In this way, there’s still a clear place for C. Projects that are small but need to be clever are maybe easier done in C than Rust. Rust is getting used more for big systems projects like VMs (firecracker), low level backends, and that sort of thing. But if I was going to write an interpreter I’d probably do it in C. Now, I’d do it in Zig.
pron|1 year ago
However, unlike Rust Zig does reject C++'s attempt to hide some low-level details and make low-level code appear high-level on the page (i.e. it rejects a lot of implicitness), it is (at least on its intrinsic technical merits) suitable for the same domains C++ is suitable for. It's different in the approach it takes, but it's as different from C as it is from C++.
bvaldivielso|1 year ago
Yes, in my opinion, but from Zig's success you can see some people are willing to trade safety for a simpler language. Different people have different values
Though to be fair you can also use zig in old C projects, moving things incrementally. I don't know how many projects do that Vs greenfield projects though
melodyogonna|1 year ago
jonathrg|1 year ago
bmacho|1 year ago
it is not very good, as
outputs 123 in debug[0] and 0 in ReleaseSafe[1] instead of giving a Runtime Error.[0] https://zig.godbolt.org/z/ezTr3zP6a
[1] https://zig.godbolt.org/z/3ExeveT69
DanielHB|1 year ago
Like say I have a really weird issue I can't seem to find locally, can I switch my production server to this different compilation mode temporarily to get better logs? Can I run my development environment with it on all the time?
dns_snek|1 year ago
For example, you can't overflow buffers (slices have associated lengths that are automatically checked at runtime), pointers can't be null, integer overflows panic.
renox|1 year ago
Not in all the ReleaseFast mode where both signed and unsigned overflow have undefined behaviour.
And there's also the aliasing issue, if you have fn f(a:A, b: b:*A) { b = <>; which value has 'a' when f is called with f(a,a)? } (not sure about Zig's syntax).
That said I agree with your classification (safer than C but isn't as safe as Rust)
hansvm|1 year ago
[0] In Rust, a smattering of those costs include:
- Explicit destruction (under the hood) of every object. It's slow.
- Many memory-safe programs won't type-check (impossible to avoid in any perfectly memory-safe language, but particularly annoying in Rust because even simple and common data structures get caught in the crossfire).
- Rust's "unsafe" is only a partial workaround. "Unsafe" is in some ways more dangerous than C because you don't _just_ have to guarantee memory safety; you have to guarantee every other thing the compiler normally automatically checks in safe mode, else your program has a chance of being optimized to something incorrect.
- Even in safe Rust, you still have a form of subtle data race possible, especially on ARM. The compiler forces a level of synchronization to writes which might overlap with reads, but it doesn't force you to pick the _right_ level, and it doesn't protect you from having to know fiddly details like seq_cst not necessarily meaning anything on some processors when other reads/writes use a different atomic ordering.
- Even in safe Rust, races like deadlocks and livelocks are possible.
- The constraints Rust places on your code tend to push people toward making leaky data structures. In every long-running Rust process I've seen of any complexity (small, biased sample -- take with a grain of salt), there were memory leaks which weren't trivial to root out.
- The language is extraordinarily complicated.
[1] Zig is memory-safe enough:
- "Defer" and "errdefer" cover 99% of use-cases. If you see an init without a corresponding deinit immediately afterward, that's (1) trivially lintable and (2) a sign that something much more interesting is going on (see the next point).
- In the remaining use-cases, the right thing to do is almost always to put everything into a container object with its own lifetime. Getting memory safety correct in those isn't always trivial, but runtime leak/overflow detection in "safe" compilation modes go a long way, and the general pattern of working on a small number of slabs of data (much like how you would write a doubly-linked list in idiomatic Rust) makes it easy to not have to do anything more finicky than remember to deallocate each of those slabs to ensure safety.
DanielHB|1 year ago
flumpcakes|1 year ago
vlovich123|1 year ago
> Explicit destruction (under the hood) of every object. It's slow.
Care to actually support this with data? C++ is quite similar in this respect (Rust has a cleaner implementation of destruction) and generally outperforms any GC language because stack deallocation >> RC >> GC in terms of speed. There’s also a lot of good properties of deterministic destruction vs non deterministic but generally rust’s approach offers best overall latency and throughput in real world code. And of course trivial objects don’t get any destruction due to compiler optimizations (trivially live on the stack). And zig isn’t immune from this afaik - it’s a trade off you have to pick and zig should be closer since it’s also targeting systems programmers.
> - Many memory-safe programs won't type-check (impossible to avoid in any perfectly memory-safe language, but particularly annoying in Rust because even simple and common data structures get caught in the crossfire).
Actually most memory safe languages don’t have issues expressing data structures (eg Java). And rust has consistently improved its type checker to make more things ergonomic. And finally if you define rust as language + stdlib which is the most common experience those typical data structures are just there for you to use. So more of a theoretical problem than a real one for data structures specifically.
> Even in safe Rust, you still have a form of subtle data race possible, especially on ARM.
I agree that for the language it’s weird that this is considered “safe”. Of course it’s not any less safe than any other language that exposes atomics so it’s weird to imply this as something uniquely negative to Rust.
> Even in safe Rust, races like deadlocks and livelocks are possible.
I’m not aware of any language that can defend against this as it’s classically an undecidable problem if I recall correctly. You can layer in your own deadlock and livelock detectors that are however relevant to you but this is not uniquely positive or negative to rust so again weird to raise as a criticism of Rust.
> The constraints Rust places on your code tend to push people toward making leaky data structures. In every long-running Rust process I've seen of any complexity (small, biased sample -- take with a grain of salt), there were memory leaks which weren't trivial to root out.
I think you’re right to caution to take this with salt. That hasn’t been my experience but of course we might be looking at different classes of code so it might be more idiomatic somewhere.
> In the remaining use-cases, the right thing to do is almost always to put everything into a container object with its own lifetime
You can of course do that with Rust boxing everything and/or putting it into a container which reduces 99% of all lifetime complexity. There are performance costs of doing that of course so that may be why it’s no considered particularly idiomatic.
My overall point is that it feels like you’ve excessively dramatized the costs associated with writing in Rust to justify the argument that memory safety comes with excessive cost. The strongest argument is that certain “natural” ways to write things run into the borrow checker as implemented today (the next gen I believe is coming next year which will accept even more valid code you would encounter in practice although certain data structures of course remain requiring unsafe like doubly linked lists which should be used rarely if ever)
anacrolix|1 year ago
zoogeny|1 year ago
Be careful not to believe your own hyperbole. Some people are loudly and persistently recommending other people to use memory safe languages. Rust may be quite popular lately but the opinions held by some subset of that community does not reflect the opinions of "everyone". It would be just as silly to say: "everyone is suggesting to move to OSS licenses".
> sholdn't [... new projects ...] be done in a memory safe language
Again, please be careful to understand where you are getting this "should". What happens exactly if you don't choose a memory safe language? Will the government put you in jail? Or will a small vocal community of language zealots criticize you.
Maybe you feel like you want to fit in with "real" programmers or something. And you have some impression that "real" programmers insist on memory safe languages. That isn't the case at all.
In my experience, making technical decisions (like what programming language to use) to avoid criticism is a really bad path.
andrewstuart|1 year ago
Rust is deeply complex.
AlienRobot|1 year ago
I don't want to write Rust. I want to write Zig. It's like Python, but blazingly fast.
3836293648|1 year ago