Hacker News new | ask | show | jobs
by Stampo00 1456 days ago
Obligatory disclaimer that I'm not trolling or trying to start a flame war.

I have dismissed Zig in the past in favor of Rust. But I've since found Rust difficult to keep up with since it's developing so rapidly and I don't use it daily.

Zig seems like it has similar goals to Rust, but with a gentler learning curve. I know the Zig community isn't as big as Rust's, but maybe I wrote off Zig too soon.

Anyone know of any objective comparisons out there? Is Zig gaining traction in a similar space to Rust?

8 comments

There does seem to have been a lot of Zig coverage recently on HN, and that's by no means a complaint. But I'm not sure that it quite goes for the same space as Rust.

I have only really kick the tyres, but it seems to me that Zig is to C what Rust is to C++, ie they both try to be the next-gen with better safety and features, but Rust's type modeling is more extensive than, and can contain complexity better than Zig, in the same way that C++ OOP is better than raw C.

Zig has a good future though, and the metaprogramming facilities are superior to most languages IMO.

Complexity and expressivity have a complicated (sorry) relationship. There are tradeoffs all around. On the one hand, a more complicated language allows you to express complicated ideas in a more compact fashion with more help from the compiler to check that what you’re doing is correct.

On the other hand, a complicated language also encourages you to use those complicated features to express yourself in more complicated ways. And this sort of thing, exercised without restraint, can lead to unreadable code. There is a lot to be said for a simple language that encourages you to write simple code and puts an emphasis on readability and maintainability over sheer power. Is Zig that language? I don’t know, but it seems like it’s aiming to be. Only time will tell whether its big statement, that we should prefer comptime code over fancy new language features or powerful macros that let us extend the language in a million ways the way we did with Lisp. I am interested to see how things develop!

Another flaw is that a more complicated language and/or one with leaky abstractions (both complex and simple rules) requires spending more mental bandwidth working around the language's pitfalls caused by complex rules. Examples include C++'s template/metaprogramming and linking rules (complex and leaky), heavy use of C macros (obscure and leaky rules, complex in use), C/C++'s header system and ODR (leaky), or Rust trying to mark most pointers as noalias and breaking programs incompatible with that model (complex and leaky) rather than embracing either referential transparency like functional languages or a "pointers are memory addresses" model like assembly/WASM.
“No alias” in Rust is a simple rule that was there from the start (it didn’t break any programs, unless by “programs” you mean “programs I would like to write in a certain way”).
By "breaking programs incompatible with that model" I think he means making it impossible (or requiring a tedious amount of uses of `unsafe`) to write code in Rust to be linked with C code if the C code contains idiom fairly common in C code.
To elaborate, there is a recurring trend of sound C programs turning into unsound Rust programs, because shared mutability is often necessary but Stacked Borrows places strict conditions on constructing &mut T (they invalidate some but not all aliasing *const T), and it's less ergonomic to work solely in raw pointers and avoid creating Box<T> or long-lasting &mut T (or for intrusive collections, any &mut T at all).

For example, matklad (the author of rust-analyzer, one of the preeminent Rust programmers and someone I'd expect to get code right) made a recent blog post on "Caches In Rust" (https://matklad.github.io/2022/06/11/caches-in-rust.html). The cache is built around https://docs.rs/elsa, which is built around https://docs.rs/stable_deref_trait/latest/stable_deref_trait..., which is unsound for Box and violates stacked borrows in its current form (https://github.com/Storyyeller/stable_deref_trait/issues/15). However, the rules may be relaxed or more ergonomic alternatives added (https://github.com/rust-lang/unsafe-code-guidelines/issues/3...), it's uncertain right now.

(Also I go by "they".)

I'd say power of expression is more closely correlated to the ability to make the code complicated. Making a large language is onoy one way to get that power.

Zig's metaprogramming is not far off being as powerful as lisp. Of rust and zig, I'd expect zig code to be more capable of turning into a hot mess more quickly.

Hopefully its simplicity and the niche it is targetting will help the community keep it somewhat in check.

How funny that you write this comment as if “comptime” is the thing that is the “simple code” alternative in this context: most static languages go with the usual angle-brackets thing for generics, which is fairly declarative and somewhat limited. Zig however has gone with a more general approach: use “comptime” functions which take types as arguments in order to specialize functions. That is way more fancy.

You can get away with not writing macros in most languages that have them. But a lot of static languages makes you use generics (parametric polymorphism) pretty frequently. And this two-stage evaluation (something like `funny(@comptime T: Type, a: T, …)`) is the simple-code flagship feature, in your book?

> most static languages go with the usual angle-brackets thing for generics, which is fairly declarative and somewhat limited. Zig however has gone with a more general approach: use “comptime” functions which take types as arguments in order to specialize functions. That is way more fancy.

This seems like you're comparing the most basic usage of C++ templates to the full generality of Zig comptime. But isn't this ignoring the fact that people write absurdly complicated template metaprograms in C++ that are very difficult to understand and debug? C, C++, and Rust require you to learn a second language to do metaprogramming, Zig doesn't.

I was comparing generics in Java and Rust with generics in Zig.
Some people think Rust is the best programming language for everything from embedded to web browsers, it's sweet spot however really is replacing C++.

Zig's sweet spot is C, and it really helps that it was made to extend C, not completely replace it.

This stance is kinda countered by actual events, i.e. Rust becoming a 2nd class citizen in possibly the most famous C project right now: Linux.
I wonder if it is actually already possible to write Linux device drivers in Zig without any "publicity fanfare", because of how easy Zig integrates with C projects and Zig's explicit approach to memory management.
That might be, but they still wouldn't let Zig code into the main tree without such fanfare.
Rust is also pushed by Microsoft for the same. I guess the motivation is that you can effectively quarantine unsafe code with it, but people will bend over backwards to use it, and the project managers are being convinced that Rust is inherently safe. If Rust automagically stops you from writing shit code you can also hire shit coders for cheap. Throw GitHub Copilot on the pile and the future of software development is here.
That's just Zig flavoured EEE.
I don't really think that Andrew Kelley and his tiny non-profit have those kind of ambitions, or really if it would matter if they would. C is the lingua franca, there is no extinguishing it.

These guys genuinely just want to make a practical, simple, common sense system programming language that let's you talk to the hardware, the operating system, and shovel bits around conveniently.

It's faaaar too early to try to get answers to those kinds of questions. What Zig's first stable release looks like still isn't fully defined, what is defined is not expected to be implemented, and what is implemented is not expected to necessarily work correctly. Zig is a really interesting project with a small community trying to make Zig happen but Zig is not, at this time, something one should be looking to compare daily usability on.

I love Zig myself but for these questions I'd say you'd need to hold off a minimum of 3 more years before you get really meaningful answers or come to any conclusions. In the meantime if language development/languages for fun doesn't interest you I'd probably not bother with Zig in that time.

Good analysis! Thanks.

For context, I was using Rust for hobbyist stuff because I value provable correctness and I love tools to yell at me if I try doing something stupid. But Rust moved too fast for me. Every time I sat down to use it, I spent more time catching up on the developments I'd missed than actually being productive.

I'm choosing instead to learn how to write C in a modern, sustainable way since at least the ecosystem won't shift from under me any time soon.

To be completely clear, I don't hate Rust. I'm not ragging on it. If I used it in my day job, the experience of keeping up with it would be a totally different story. But for hobby and personal stuff, I need something where I can be productive whenever I find the time to devote to it.

Is there an estimate on when they will freeze the core language itself? Are they still making core syntax or semantic changes? I'm planning to take a look at zig for hobby projects and can live with stdlib changing, but have to wait if they are still making wholesale changes.
Zig has direct C FFI on the source code level, in some ways it has access to a much bigger community.
Zig is not memory-safe (without quarantining allocations forever which is insufficient for production). Rust is. This is an enormous difference which affects everything about these languages. For example, the "gentler learning curve" in Zig is precisely a result of not being memory safe.
> quarantining allocations forever [..] is insufficient for production

In most cases that's true, but not all. ARM MTE + quarantine has just 1-2% overhead as tested on Chrome:

https://security.googleblog.com/2022/05/retrofitting-tempora...

Perhaps we'll see such techniques used in newer languages like Zig.

(This doesn't detract from your main point, of course - yes, Zig is simpler because it has less safety.)

The approach described there is significantly different from Zig's approach, which doesn't use MTE and quarantines forever. Note that Chromium never seriously considered quarantining forever as Zig does because leaking every allocation less than 4kB unless all allocations in that page are freed is not production viable.
True, but I don't think Zig is committed to that particular idea and nothing else.

Yeah, quarantining forever is going to have much more memory overhead. It might be fine for some use cases, but not a browser or anything else complex + long-running, I agree.

it is a strength, and the reason why i picked Zig over Rust

i want to control lifetimes and memory management, so i can target the hardware i want, and i can play with memory the way i want to do tricks and optimizations that could not be possible with a rigid language like rust(that is very slow btw)

the day zig adds borrowchecker or some lifetime enforcment shenanigan will be the day i'll look for an alternative

It's more memory-safe than C, which is being used in production in billions of places right now.
My biggest issue with zig is that it is immature programming language. Breaking changes can occur at any point and bugs can be introduced at compilation step. So with a bit of unlucky your coding experience might end up a hell.

Not a fan of Rust too though and like the zig idea in general.

That's what scared me off from learning Elm. It's mostly a one-person project. Naturally, it moves really slowly. Breaking changes can happen with any given release. And the community of developers is very small.

It's a shame, too, because there are a lot of really exciting ideas in the language. But unless you're working at NoRedInk with the lead developer, you might be better off sticking with tech that's a little more boring and less cutting edge, especially if the thing you're using it for is supposed to be making you money.

Isn’t Zig…not really production-ready? I was under the impression it was still a bit of an experiment. I’m aware of people using Rust in production on large-scale systems, but not Zig.
Trolling? Language-specific submissions invariably end up as either metadiscussions about the language or as PL comparison discussions. You’re as on-topic as anyone else here.
The biggest issue with Zig is that IMHO it isn't "revolutionary" enough. It has been shown time and time again that in order to do the jump from niche to mainstream a language _needs_ to either have a huge corporate backer behind (look at Go or Swift) or it must truly be revolutionary (i.e. Rust and compile time memory safety).

Zig has neither, and the sad truth is most developers will not make the jump from C and C++ and throw decades of skills out of the window unless they really have a lot to gain. This is true for Rust: you get compile time guarantees that your programs are memory safe and have no data races. That is enough for most to conclude that Rust has a shot to replace C/C++. But Zig? Like Hare, V, .. it mostly boils down to syntactical sugar, and then you have not only to compete with the rest of the crop of "C replacement tools", but with C + a static analyzer too.

If you forget a defer, you will leak memory, and if you have to deal with Valgrind and the likes anyway you are better off sticking with C and static analysis tools - with the added bonus that it's vastly easier to find skilled developers.

I know, I'm personally a language nut and I love using new languages, but personal preferences are not a great factor when pushing for wider adoption, because most developers out there don't really care about that and would rather use a tool they already know about and they are confident with.

What might make Rust success will be the fact it saves people time and money, and that is demonstrably true. Project Managers will definitely listen more to that argument than to "but it's shiny and new".

> Zig has neither, and the sad truth is most developers will not make the jump from C and C++ and throw decades of skills out of the window

But that's exactly Zig's killer feature. As a C or C++ developer you don't need to throw your decades of skills out of the window. Instead you can start coding productively in Zig in a weekend. And you don't need to throw away your C (or C++, or Objc) code either, you can just integrate it into your Zig project and it's exceptionally easy to do so.

If that isn't "revolutionary" compared to other, bigger languages which try too hard to be revolutionary but then go on to build out their own little island paradise separated from the rest of the world I don't know ;)

(also if you're looking for an actually revolutionary single feature in Zig, check out how elegantly Zig's comptime feature enables generics and reflection)

The entire point of Zig is that you don't throw that C knowledge out, you turn it into Zig knowledge in 30 minutes.

"If you forget a defer, you will leak memory"

There is a bit more to it than just plastering defer all over. If you are designing something in a system programming language like a data structure you must know how to achieve memory safety, and might even want other properties like liveness guarantees. It's not like Rust can do this for you automatically in all, but the more trivial cases. There is unsafe Rust, and it's strictly worst than Zig as a C replacement.

On the other hand for simple API-consuming applications Rust is needlessly complicated. You throw time and money out of the window with it.

Rust's sweet spot is replacing C++.