Zig is a very low level language. I think the fancy type system can trip up people into thinking they are working with a high-level language. Zig is basically C with a fancy type system, so you should not expect things like special String types, overloading of index based access etc. I think the author was thinking that Zig was very close to Rust or C++, when in reality it is much closer to C. I had to keep reminding…
Interesting. I had the impression Zig proponents were praising it because it wasn't as low-level as Rust.
Failing to Learn Zig via Advent of Code
261–270 of 338 posts
Re: Failing to Learn Zig via Advent of Code
#262Earlier quoted context omitted.
From a programming language design space, it's much more like C++. However it can occupy some niches that C can but C++ does poorly because of zero cost abstractions, I think. (Very handwavy)
There are no niches where Rust can do better than C++. In many places Rust can, uniquely, match C++.
Re: Failing to Learn Zig via Advent of Code
#263Earlier quoted context omitted.
> But he is right that "no hidden control flow" is an anti-feature. Hmmm, "no hidden control flow" is at least what I want writing distributed systems, storage engines or device drivers. Calling it an "anti-feature" is dismissing important domains for system languages where control flow in the control plane needs to be explicitly visible, and where the necessity for things like static allocation and NASA's "The Power…
Destructors are a powerful tool to ensure that required events occur, an important part of safety-critical coding. Static allocation is a valuable method that is wholly compatible with use of destructors. If you imagine that freeing dynamically-allocated memory is the main use for destructors, you have utterly failed to understand them.
I suppose we differ mostly not in our view of destructors, but in our approach to reducing dimensionality and how best to do that.
Re: Failing to Learn Zig via Advent of Code
#264Earlier quoted context omitted.
I still can't figure out how Zig proposes to prevent undefined behavior without a borrow checker (aka MLKit regions) or GC. AFAICT the answer is "inject as many runtime checks as needed" although the docs seem to go way out of their way to avoid making this explicit.... or deal with the fact that these checks are now runtime failures rather than compile-time failures, and therefore need code to handle them. It seems…
You're conflating undefined behavior with spatial/temporal memory safety, the latter of which is what is 100% prevented by Rust's borrow checker, provided you're not interfacing with hardware, in which case I believe that things change more in binary fashion. However, Zig treats memory safety not as an extreme-at-all-costs but as a spectrum (there are reasons for wanting to think like this, at least when writing low-…
You are correct; I should have written "memory safety".
> Zig treats memory safety not as an extreme-at-all-costs but as a spectrum
Zig needs to be more forthright about this.
When I first heard about Zig, I googled "zig vs rust" and found an article on the Ziglang website addressing that very topic:
https://ziglang.org/learn/why_zig_rust_d_cpp/
It completely fails to mention memory safety at all. That seems extremely dishonest, since memory safety is basically the "headline feature" of Rust (well, one of two or three at most). I wasted a lot of time digging through the Zig language manual ("so then how do they...") before concluding that something didn't add up. It definitely left a bad taste in my mouth.
> Rust won't protect you from all undefined behavior ... Rust has checked arithmetic off by default in safe builds
That didn't surprise me at all, nor will it surprise anybody who knows Java. Modular arithmetic is perfectly well-defined.
It's only C/C++ that picked the crazysauce option of decreeing that signed overflow is totally equivalent to scribbling all over random pieces of memory. It isn't overflow that's a security risk; it's languages that define overflow to be undefined in order to squeeze out a few piddly loop micro-optimizations. This becomes increasingly less beneficial in languages with iterators and no backward-compatible-with-C burden. Details (scroll to "Myth: overflow is undefined"):
https://huonw.github.io/blog/2016/04/myths-and-legends-about...
Re: Failing to Learn Zig via Advent of Code
#265As a seasoned Zig programmer, this is good information, though painful to read. A lot of the problems seem to be from a fundamental misunderstanding of Zig's philosophy and very basic things about how the language works. Possibly Zig needs more emphasis on those things in its documentation. I also have to wonder about a fundamental misalignment of thinking when someone says downloading and replacing a single .exe is…
As a rank beginner, I had no problem learning these things ... they're mentioned repeatedly in material about Zig both from the project and from outside descriptions, the philosophy is the output of `zig zen` and in all the documentation, etc. The OP couldn't figure out how to print despite the Hello World program at the beginning of the Zig Reference Manual. I think most of the issues here are PEBKAC.
Re: Failing to Learn Zig via Advent of Code
#266To me the biggest difference between Rust and Zig in practical terms is that Zig does not offer statically safe resource management like Rust does, and as far as I know they have no intentions of doing so in the future because they think it’s less important than all this stuff about control flow. There are a lot of interesting ideas in the language but my disagreement with them on this issue is so fundamental that I…
For example, to get the conversation started, how do both languages compare in terms of checked integer arithmetic? Do they enable checked arithmetic by default in safe builds with an opt-out for performance, or do they leave default builds unsafe with an opt-in for safety?
Another example, JavaScript is 100% memory safe, does it follow that we can expect to see less exploits against NPM than C? Both ecosystems are massive, but I'd wager that most product release security teams are more stressed out about NPM than C dependencies right now. Not to say that they shouldn't be running C dependencies in sandboxes or be evaluating the risk of C (and remember that Zig is an order of magnitude safer than C, much closer to Rust actually, and more so in some areas). But NPM is probably getting more attention. Same thing for bug bounty issues reported. Probably more for NPM supply chain vulnerabilities than anything else. All 100% memory safety, and yet security is still a thing.
It's the many small decisions like these, along with thinking of security not as a binary extreme but as a probabilistic spectrum, that are more interesting to me.
Re: Failing to Learn Zig via Advent of Code
#267As a seasoned Zig programmer, this is good information, though painful to read. A lot of the problems seem to be from a fundamental misunderstanding of Zig's philosophy and very basic things about how the language works. Possibly Zig needs more emphasis on those things in its documentation. I also have to wonder about a fundamental misalignment of thinking when someone says downloading and replacing a single .exe is…
If there are fundamental philosophies in a programming language (and there usually are), tutorials ought to begin with lots of tiny example programs that exemplify those fundamentals. They should continue with examples of gradually increasing complexity, but ALWAYS using those same fundamentals in various combinations to show how those fundamentals are intended to work together in all sorts of ways. If the tutorials…
Re: Failing to Learn Zig via Advent of Code
#268As a seasoned Zig programmer, this is good information, though painful to read. A lot of the problems seem to be from a fundamental misunderstanding of Zig's philosophy and very basic things about how the language works. Possibly Zig needs more emphasis on those things in its documentation. I also have to wonder about a fundamental misalignment of thinking when someone says downloading and replacing a single .exe is…
Nah, I think it is fine. The problems are almost all (the author's) problems with zig's philosophy of "when to do things you need for a 1.0". Author mostly wants docs, guides, error messages, and package manager, which are supposed to be "late in the development process" according to my understanding of the unofficial zig roadmap.
Re: Failing to Learn Zig via Advent of Code
#269Earlier quoted context omitted.
You're conflating undefined behavior with spatial/temporal memory safety, the latter of which is what is 100% prevented by Rust's borrow checker, provided you're not interfacing with hardware, in which case I believe that things change more in binary fashion. However, Zig treats memory safety not as an extreme-at-all-costs but as a spectrum (there are reasons for wanting to think like this, at least when writing low-…
> You're conflating undefined behavior with spatial/temporal memory safety, You are correct; I should have written "memory safety". > Zig treats memory safety not as an extreme-at-all-costs but as a spectrum Zig needs to be more forthright about this. When I first heard about Zig, I googled "zig vs rust" and found an article on the Ziglang website addressing that very topic: https://ziglang.org/learn/why_zig_rust_d_c…
Yes (and thanks for the link!), I was in fact thinking more of this non-UB case (not signed overflow UB) as an example of where it's clearly defined as wraparound but can be chained into an exploit nevertheless, not technically UB but a vulnerability nevertheless. Not all exploits bother to go as far as a UAF. Unchecked arithmetic can be low hanging fruit.
> That didn't surprise me at all
It surprises me that Rust doesn't just enable checked arithmetic by default with an opt-out for performance, rather than enabling it by default for performance with an opt-out for safety. Zig's choice here is the safer choice from a security perspective.
Re: Failing to Learn Zig via Advent of Code
#270Earlier quoted context omitted.
> You're conflating undefined behavior with spatial/temporal memory safety, You are correct; I should have written "memory safety". > Zig treats memory safety not as an extreme-at-all-costs but as a spectrum Zig needs to be more forthright about this. When I first heard about Zig, I googled "zig vs rust" and found an article on the Ziglang website addressing that very topic: https://ziglang.org/learn/why_zig_rust_d_c…
> Modular arithmetic is perfectly well-defined. Yes (and thanks for the link!), I was in fact thinking more of this non-UB case (not signed overflow UB) as an example of where it's clearly defined as wraparound but can be chained into an exploit nevertheless, not technically UB but a vulnerability nevertheless. Not all exploits bother to go as far as a UAF. Unchecked arithmetic can be low hanging fruit. > That didn't…
It means that every arithmetic operation is potentially a branch/jump instruction. This wrecks a lot of pipelining/out-of-order-execution schemes.
I once worked on an exotic architecture where the integer types had a "NaN" value just like floating point numbers do; it had both modular and checked arithmetic, but the checked versions would return NaN instead of branching.
It also had 37-bit integers. Yes, 37-bit. Fun times.