Zig and the Design Choices Within
Key topics
The article discusses the design choices made in the Zig programming language, sparking a heated debate among commenters about the language's strengths and weaknesses, particularly regarding memory safety and comptime.
Snapshot generated from the HN discussion
Discussion Activity
Very active discussionFirst comment
2h
Peak period
115
0-12h
Avg / period
16
Based on 160 loaded comments
Key moments
- 01Story posted
Nov 10, 2025 at 10:42 AM EST
about 2 months ago
Step 01 - 02First comment
Nov 10, 2025 at 12:22 PM EST
2h after posting
Step 02 - 03Peak activity
115 comments in 0-12h
Hottest window of the conversation
Step 03 - 04Latest activity
Nov 15, 2025 at 6:52 AM EST
about 2 months ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.
For most languages I can usually see one or two “killer features” that push the language: For Rust is taking C space with memory safety + modern semantics, for Go is being easy to learn by most engineers + parallelization, for Ruby is ergonomics…
I don’t see any similar pitch for zig other than a general “I kinda enjoy it”, and the language seems to have a couple red flags, so why focus on it? (Honest question).
My impression is that this is the main thing for Zig too. The intersection of the set of languages that let you write very low-level code where you have full control over memory and allocation and the set of languages that are enjoyable to program in is pretty small.
C is in there if you've internalized many of its warts are fine with all of the many many footguns it has. C++ is in there if you much of your enjoyment comes from the machismo of feeling like you have conquered C++'s beastly language complexity. Rust is in there if proving to the compiler that you know what you're doing is satisfying to you.
Zig sort of gets out of your way like C does, even when what you're trying to do is potentially harmful. But it's more modern and expressive and doesn't have all of C's historical baggage.
Is that a stated goal of the language? Other than the feature to gradually move from c++ it wasn’t super clear from the main pitch.
I wouldn't say "cumbersome", but perhaps "full of warts and historical baggage".
They have some more details here: https://ziglang.org/learn/why_zig_rust_d_cpp/
It's better at that than Rust because it's less abstracted, and it's better at that than C because you don't have to worry all the toolchain nonsense / weird conventions / weak type system of the C ecosystem.
As a small example wrt Rust: resetting an arraylist/vector while reusing its memory is a weirdly complicated trick https://lobste.rs/s/emvkea/why_we_didn_t_rewrite_our_feed_ha...
I think I don't need to provide references for C.
It's a new pathway to mastery that really works well for some people. That in itself is much more valuable than any new specific feature the language has to offer, although the ability of the toolchain to cross-compile reliably not only Zig but also C and C++ code does play into that.
And, while not yet 100% there, instant incremental rebuilds also help to achieve faster feedback loops.
People like Zig because it's a tool that helps them become better programmers, faster.
A bit of a nitpick here: the trick is for creating a new vector of a different type, that reuses the allocation of an existing vector, using only safe code. "Resetting an arraylist/vector while reusing its memory" is just vec.clear() if you're not changing the type. And it's trivial to change the type of a vector with unsafe (the docs even have examples of this); the only advantage of the "trick" is to ensure you'll get a panic if you screw up the alignment of the types.
And after that blog post, the Rust team accepted a proposal to introduce a vec.recycle() function to change the type of a vector without needing that trick (and with compile-time checks for alignment compatibility): https://github.com/rust-lang/rust/pull/148416
But that example aside, I agree with your overall premise -- Zig and Rust share different design goals here, and Zig's lower level of abstraction makes it more approachable to learn than a language like Rust.
Nitpicking? Let’s show an example on creating an interface in Zig to see all complicated tricks.
I have no idea if Zig will be successful or not, but even if you look just at memory safety, I think it does a better job at that than Rust. If you look at MITRE's top 25 dangerous weaknesses [1] or top 10 exploited weaknesses [2], you'll see that Rust spends almost all of its complexity on eliminating weaknesses that don't even make the top 5 on either list, while Zig's more limited memory safety addresses the more dangerous memory-safety-related problems without paying so dearly to solve less severe issues.
Now, I personally think that Zig's combination of expressivity and simplicity, while still being low-level, is an unprecedented killer feature (I wrote more about it here: https://news.ycombinator.com/item?id=45852774) which makes the language design quite revolutionary and fascinating. This could perhaps translate to correctness benefits.
[1]: https://cwe.mitre.org/top25/archive/2024/2024_cwe_top25.html
[2]: https://cwe.mitre.org/top25/archive/2024/2024_kev_list.html
Uh? Number 2 in CWE is an out-of-bounds write, and the same vulnerability is number 1 in the KEV list.
I'm not saying it's not important, but we do have to consider whether it's worth the cost.
> And most of the things the things above it (other than out of bounds writes/reads which you addressed in another comment) are not something I would consider a programming language can directly affect (e.g. SQL injection, CSRF)
It actually can.
If it was about just lifetimes, Rust would be a much friendlier language. Sometimes I wonder if a less rigorous Rust would be more popular.
In contrast if Rust only ensured that a reference doesn't outlive the scope it's valid in (allocated and cleaned up via RAII), a lot of problems with Rust would go away, like you could have 2 mutable references pointing to the same thing - it'd still be leak free, but you could have data races, and would need some aliasing heuristics like you have in C.
Still most of the complaining of the borrow checker would go away. Imo this is an idea worth exploring in a language, but I'm sure doing this would upset Rust purists.
Preventing memory leaks isn't normally what people mean by "memory safety".
As an aside: a common memory management approach used in Zig is to have a dedicated memory pool for an operation and simply free all of the memory after the operation is over instead of freeing individual allocations.
People do sometimes expect it to be encompassed by memory safety, even though the Rust documentation clearly states that it does not prevent memory leaks in safe code and offers several obvious ways to deliberately leak memory.
This is simply untrue. Zig offers the same spatial memory safety as Rust does, and that is the kind of memory safety that prevents more dangerous vulnerabilities [1] than the kind Rust offers and Zig doesn't (temporal memory safety).
> if you don't free something manually it won't get freed
Rust also isn't free of memory leaks, and doesn't even pretend to guarantee that all allocations are freed. Lack of memory leaks doesn't fall under what Rust defines as memory safety (which Rust defines as guarantees it does provide, excluding those it doesn't).
[1]: https://cwe.mitre.org/top25/archive/2024/2024_cwe_top25.html - Rust and Zig's memory safety prevent #2 and #6 on the list. Rust, additionally, prevents #8. C prevents none of those.
Zig doesn't have the memory safety mechanisms of C++ level shared_ptr/unique_ptr.
It's essentially C's malloc/free with the added safety of defer (or possibly arenas), but making sure that the program doesn't leak memory (or have use-after-free bugs) falls on the programmer.
And memory leaks are a much lesser problem, as they usually lead to crashes in OoM situation, than gaining access to random blocks of memory.
Besides, the way you trigger memory leaks in Rust/C++ is with circular references, which are much harder to create than just missing a free() somewhere.
If you have memory that's not tied to a function scope's lifetime in Zig (or the scope of an allocator), then you're essentially have to go by C rules
Zig's memory-safety is spatial, which is the more dangerous kind. Your examples are all temporal, and I don't know if I would call them "safety" as the language doesn't enforce or even encourage their use. For example, I work on one of the world's most foundational C++ projects (the HotSpot virtual machine), where neither shared_ptr nor unique_ptr are used at all; the language doesn't complain. There are reference-counted pointer libraries for Zig, too (although I don't think they're popular).
> It's essentially C's malloc/free with the added safety of defer
No, it isn't. First, unlike C or C++, it offers Rust-like spatial memory safety (again, the more important kind). Second, allocation in Zig is much more explicit than in C or C++.
> Besides, the way you trigger memory leaks in Rust/C++ is with circular references, which are much harder to create than just missing a free() somewhere.
They're also much harder to detect, especially when you have a very explicit memory allocation scheme.
> If you have memory that's not tied to a function scope's lifetime in Zig (or the scope of an allocator), then you're essentially have to go by C rules
Again, Zig doesn't seek to offer temporal memory safety, but it does offer the same level of spatial memory safety as Rust does, and while the "rules" of temporal management are similar to C, the way allocation works in Zig makes for a very different experience. An allocating function in Zig looks very different from its C counterpart.
Zig rejects the temporal memory management schemes of C, C++, and Rust - each for different reasons - and prefers a different kind. Of those, only Rust offers temporal memory safety (in the sense that it's controlled by the language) - albeit for a price - and the rest don't.
I also don't understand how one can sidestep the issue of ownership of memory - let's say you have a situation where a given piece of memory has changing or ambiguous ownership - like an event sent between two components, that has allocated some dynamic memory.
I'm not saying this just because, I've encountered this exact issue before - many C libraries have event systems where the ownership is not obvious coming from the code - like the sender owns the event, and if you store a reference to it, then you have a dangling pointer if the sender decides to clean it up.
That's why it's important to make it either obvious who owns what, or have some automatic system like GC or unique_ptr or the borrow checker.
This is a very real issue and the only way you can fix it is to follow strong informal conventions the language has no way of enforcing or even communicating to the user.
You mention Zig has a temporal memory management solution of a different kind - may I ask you what it is, because I haven't really seen it.
That two bugs result in the same or similar outcome doesn't mean they're as common or as equally exploitable, which is why, in practice, it is distinctly a more dangerous weakness in the lists maintained by MITRE.
> I also don't understand how one can sidestep the issue of ownership of memory
It's not about side-stepping. There are many kinds of bugs in software, and while we'd like to avoid all of them, some problems are, in practice, more problematic. After all, Rust similarly "sidesteps" - as in doesn't prevent - all non-memory-safety-related weaknesses, some of which are more dangerous than dynamic memory safety. If Zig isn't good enough because it doesn't prevent temporal memory safety violations, then by the exact same logic, Rust isn't good enough because it doesn't prevent, say, injection vulnerabilities, that are more dangerous than temporal memory safety vulnerabilities.
> I'm not saying this just because, I've encountered this exact issue before
Sure, it's a real and serious issue. But injection is a more serious issue, which Rust doesn't prevent, and spatial memory violations are also a more serious issue, which Zig prevents just as Rust does.
> That's why it's important to make it either obvious who owns what, or have some automatic system like GC or unique_ptr or the borrow checker.
It is, but it's even more important to prevent code injection attacks, yet Rust doesn't do that. It all comes down to how much it's worth it to pay to prevent certain bugs.
Rust was built because its designers believed that memory safety wasn't worth paying the higher memory footprint or the lower predictability of more popular memory-safe languages, or else there would have been no need for Rust in the first place. Similarly, it's just as reasonable to believe that the price you pay for temporal memory safety in Rust is not worth it.
> You mention Zig has a temporal memory management solution of a different kind - may I ask you what it is, because I haven't really seen it.
It's not a safe solution by any means (as the language doesn't enforce temporal memory safety, just as C++ doesn't), but memory allocation and deallocation in Zig is not the same as in C or C++. In particular, Zig functions that allocate are explicitly marked by having an Allocator parameter (https://zig.guide/standard-library/allocators/). Unlike in C, in Zig you know which functions allocate and using which allocator. That's how Zig is such a great fit for arenas.
Because Zig is built around custom allocators, you can also choose allocators that offer use-after-free, double-free, and memory-leak protection, and do so selectively (unlike in C): https://sinclairtarget.com/blog/2025/09/getting-my-allocator...
C is very basic and (especially when you stick to something like C99), can be very tedious to write. In C, if I hope for smarter things I need to write them by hand; usually there are no ways of achieving some goals without just crunching out the code. Zig preserves C qualities but also gives some extra tools that are completely optional and makes it less tedious than C.
I believe that Zig's popularity is also caused by general tendency of some people. Some prefer to fix a segfault than spend half a day refactoring something that was supposed to be easy but is causing half of the codebase to be rewritten.
(Oh, and Zig is also an escape hatch to easy CGo :))
In other words, "I kinda enjoy it"?
So to sum up : A powerful C without the quirks that manages to keep things simple but is also a batteries-included experience with a smooth adoption path. What's not to love ?
Every single commonly-used programming language has a couple red flags, often much more than a couple. Javascript, C, C++, Go, Python - these languages all have serious flaws and are nonetheless used by extremely large numbers of people for all sorts of tasks.
I find Zig to be a pleasant option for code that requires high performance. I find it strictly dominates C as an option, as Zig outperforms C on every criteria I care about in a language's developer experience.
I often see people compare Zig to Rust and complain that Zig doesn't have Rust's safety guarantees. I don't know Rust, but looking at it casually, the language itself seems to have a lot of complexity that doesn't appeal to me, and I'd still prefer Zig to Rust. If I need memory safety, I'd rather write in Go or Python.
When I read articles like these, the gotchas they find don't seem that compelling to me. It's always like if you write your code in a deliberately confusing way to confuse the compiler, you can get incorrect results, but I don't care because I would never write code like that.
otherwise, not sure who the audience of this piece is supposed to be, but it's written in a pretty combative tone, which will not be persuasive to anyone who isn't already persuaded, so i guess more of a rant than anything worth sharing here
so if you wanna talk about it you at least gotta say which definition you're using
That's because Zig defers a bunch of checks to runtime that Rust will force you to deal with before it will let you compile at all.
That is a tradeoff. Developer velocity vs memory safety.
Given that Bun seems to be beating Deno on most metrics, it seems like that was the correct choice for Bun.
For example, it would be interesting to compare how many Rust bugs mentioned crashes back when there were only 13k bugs reported, and the same for the JS VM comparison. Don’t get me wrong, as a Rust zealot I have my biases and still expect a memory safe implementation to be less crashy, but I’d be much happier concluding that based on stronger data and analysis.
Actual SIGSEGVs are pretty rare, even during development. There was a pretty interesting one that affected our fuzzing infra a little bit ago: https://ziggit.dev/t/stack-probe-puzzle/10291
Almost all of the time we hit either asserts or panics or other things which trigger core dumps intentionally!
- deno 44: https://github.com/denoland/deno/issues?q=is%3Aissue%20state...
- bun 464: https://github.com/oven-sh/bun/issues?q=is%3Aissue%20state%3...
That is a bias. You want all your "memory safety" to be guaranteed at compile time. Zig is willing to move some of that "memory safety" to run time.
Those choices involve tradeoffs. Runtime checks make Zig programs more "crashy", but the language is much smaller, the compiler is vastly faster, "debug" code isn't glacially slow, and programs can be compiled even if they might have an error.
My personal take is that if I need more abstraction than Zig, I need something with managed memory--not Rust or C++. But, that is also a bias.
You may potentially like D. Its tooling leaves much to be desired but the language itself is pretty interesting.
I don’t think comptime as just some macro system. It is closer to a reflection system. I use comptime to access types. You can create specialized paths depending on type.
Also imo generics are “first class” in zig. Comptime is first class and thus generics are too.
Is everything first class, then?
This anything implements with macros are not first class
> I am personally a proponent of a good macro system.
Comptime is much more constraint than any macro system: no code generation (including AST rewrite), no arbitrary tokens. Thus it's much harder to "go overboard" with Zig's comptime. This constraints of cource have their drawbacks, but code generation is still a thing.
> Much of Zig seems to me like "wishful thinking"; if every programmer was 150% smarter and more capable, perhaps it would work.
Nice way to put it! But I oppositely believe the world needs more tech that treats professionals as experts, not kids.
That’s how it was until around the turn of the century. Who needs types, we’re adults after all. Memory safety and garbage collection? Oh please go back to kindergarten.
But then some of us learned that no matter how smart we are, we can make mistakes that those things can actually prevent. And those mistakes can have catastrophic consequences. Professionals should go for tools that help them prevent those mistakes, right??
That's true but it's deeper than that -- no matter how much time goes by, there will always be people new to the language, and they will always make newbie mistakes if the language allows them to. So "just be an expert and don't write shoddy code" doesn't scale, no matter how hard you personally try.
"Memory safe languages" are tools that prevent professionals from making those mistakes.
It's a subtle but important difference. Zig attempts to leave some humanity to the developer.
When someone says they are incapable of earning or deserving that, I feel sad.
Zig does not ignore that particular danger, it just takes a different approach to dealing with it than some other modern languages. An approach that, I believe, leaves the developer with a little more humanity by allowing them the benefit of the doubt that they know what they are doing.
Everyone that has not built a systems language, or has not built a real application with both Zig and a memory safe language, that is reacting emotionally to what I've said should put a lot of consideration into whether they are cargo culting or using critical thought. Consider that we still do not yet know what is best, and shutting down attempts to explore different ideas with things like "creating [and using] this language is ignoring the humanity of the end user" is, well.. dumb.
Of course, caveats apply: it is certainly simple compared to some languages, but certainly not compared to others. "Famously simple" seems to indicate it is one of the simplest languages to learn, which seems wrong unless there are some serious qualifications to that statement?
If you don't know anything about using a systems language, Zig makes it easier for the people who do to review your code and make sure you didn't mess it up. It does this with very intentional design that makes it easier to understand the full impact of code quickly, reducing the cost of review, making review practical to catch the issues. It also has many other fail safes to catch these problems before they ever reach a production release.
So, yeah, it's totally depending on where you are coming from -- but Zig is not a tool built for a web developer who doesn't know anything about memory to go and ship an application within their first week. It does make it easier for that person to learn the ropes at a steady pace.
Meanwhile, everyone complaining that Zig is not memory safe doesn't seem to care that applications written in Zig do not have the vulnerabilities that memory safety solves on the scale that C does[0].
If you have not written a real application in Zig and evaluated it for vulnerabilities, but are claiming that creating Zig was irresponsible, and using it is too; you are cargo culting.
If you have, you probably understand there is a niche that Zig fits in and that it isn't surprising it exists to fill it. Like all things in our industry, there is a cost/benefit analysis required for choosing the tools you build with.
No one reasonable has claimed that memory safe languages should not exist, but there is a maddening number of people being disrespectful toward those who think there are other ways of addressing the same problems.
[0]: https://mitchellh.com/writing/ghostty-gtk-rewrite
Similarly, one can claim that pretty much anything compiles "incredibly fast" if one compares with Rust, C++ and Swift.
But comparing to worst in class doesn't actually say anything.
One note about this:
> If you have not written a real application in Zig and evaluated it for vulnerabilities, but are claiming that creating Zig was irresponsible, and using it is too; you are cargo culting.
I don't know what this has to do with my comments at all, but I want to point out that you are using "cargo culting" wrong. This describes imitating practices of something successful, thinking that by this imitation, success will follow as well.
> No one reasonable has claimed that memory safe languages should not exist,
Again, I have not talked anything about whether memory safe languages should or should not exist. You are confusing me with someone else.
It's easy to get in a car and put your foot on the pedal, but usage entails not crashing.
>Memory safety is one of a million ways it can be dangerous.
We have the statistics on this. It is 7 out of 10 ways it is dangerous, going by proportion of CVEs, so it's likely higher in less well tested software. Your estimation was off by 5 orders of magnitude.
>leaves the developer with a little more humanity
I could care less if the developer is afforded humanity. I want to write software and I want a programming language that helps me to do that. Whatever humanity I'm sacrificing by writing in memory safe languages is more than made up for by the comparative ease of not having to worry about memory safety.
>reacting emotionally
You are reacting emotionally. You are judging programming languages by their emotional value rather than their features. “Humanity” is not a measurable feature. 70% fewer CVEs is a measurable feature.
Some of our problems are novelties because before Grace Hopper basically nobody is writing software so there aren't centuries of lessons in how to do it properly - but this problem isn't like that, all the safety critical industries could tell you that "professionalism" won't prevent the mistakes and what you need is mechanism so that the mistakes cannot happen.
Let me give you an example I like from the railways, which are about twice as old. One night, signaller comes on duty and during the day a team of engineers have been doing work on "his" signal box. Still, things seem to check out and he gets to work, a train approaches, he tries to give them their whole route but their next signal seems stuck and won't "pull off" from danger - he blames the engineers of course. In accordance with regulations the train's driver phones the signaller, signaller explains that he can't release the signal but gives the driver authoriation, per standard instructions, to pass only one signal and proceed at caution (ie slowly enough to stop short of any obstruction) to the next signal. The next signal though is the same, the signaller is annoyed, blames the engineers again, same order to proceed at caution. The next signal is the same again. But, just after the driver receives their authority and passes that signal the signaller gets another call. Funny, surely they haven't reached the next signal yet? No. They're face-to-face with another train. Some junction points ("switch" if you're American) have failed, the train has been sent into another, both stopped short and nobody is injured.
The points failure had been detected. If the signaller had carefully checked his instruments they'd have told him that this failure had occurred and that is why it wasn't clear to set those danger signals off which is why, try as hard as he could, they could not be pulled off. It is mechanically impossible, not because of professionalism, or capability or any other brave words but physically impossible to kill everybody by clearing the conflicting signals in this state.
Mechanism.
... and the same could be said about Rust, only with Rust we can already see that it suffers from relatively low adoption at a relatively advanced age.
The funny thing about that claim is that it leads to an obvious question: if working harder to satisfy the compiler is something that requires less competence than other forms of thinking about a program, then why Rust? Why not ATS? After all, Rust does let you eliminate certain bugs at compile time, but ATS lets you eliminate so many more.
As in, why not use a language with much stronger formal verification? Because people have tried it and failed.
Like you said, Rust is hard, it already feels at the limit of what people can handle.
But unlike ATS, many people have tried Rust and succeeded, and some Rust programmers even claim that they become very productive with it after a while. I very much doubt the same could be said about ATS.
So if Rust is preferable to ATS because more people are productive with it despite ATS being able to guarantee more at compile-time, then by that logic a language that more people would be productive with than with Rust, despite Rust guaranteeing more at compile time, would be preferable to Rust.
You see, the problem is that these arguments cannot lead us to an objective preference unless we compared Rust to all other points on the spectrum, especially since Rust proponents already must accept that the best point is not on any extreme. So we know that languages that guarantee more than C but more productive than ATS are preferable. Guess what? Zig is right there, too, so that argument can't be used to prefer Rust over Zig.
I think where we disagree is that you believe Zig is as safe as Rust (by making it easier to make other things safer). I don't believe so (my first impression of Zig was Bun repeatedly segfaulting), and I'm just sad that people are choosing the easy route and going for more insecure software, when it finally looked like we made such great progress, with a language people can actually use. I agree with simpler, but there's so many other things that can be changed or removed from Rust, and still leave in lifetimes, or something similar.
Quite the opposite. Rust is definitely safer in the simple sense that it guarantees more memory safety. But that's very different from saying that Zig is closer to C than to Rust (Zig's memory safety is much closer to Rust's than to C's), and it also doesn't mean that it's easier to write more correct/secure software in Rust (because there are just too many factors).
> and I'm just sad that people are choosing the easy route and going for more insecure software
The jump from "segfaulting" to "insecure" is unjustified, as not all causes of segfaults map to equally exploitable vulnerabilities. Java programs, for example, segfault much less than Rust programs. Does that mean Rust programs are significantly less secure?
This is arguable. Zig's issues with memory safety are not limited to such things as use-after-free ("temporal" memory safety in a rather obvious sense). Without something very much like Rust's borrow checker and affine types, you can't feasibly prevent a program from inadvertently e.g. stashing a pointer somewhwere to an inner feld of a tagged union, and reusing that pointer later even though the union itself may have mutated to a different tag, which results in undetected type punning and potentially wild pointers. The issue of iterators to a collection being invalidated by mutation is quite similar in spirit, and again has nothing to do with the heap per se. Rust prevents these issues across the board. The fact that it also manages to prevent temporal memory unsafety altogether is simply a bonus that essentially comes "for free" given the borrow checking approach.
That's not arguable. Because if we say that memory safety is important because it prevents some common and dangerous vulnerabilities, then Zig clearly prevents the most dangerous of those, while C doesn't.
> you can't prevent a program from inadvertently...
Now you're naming more problems that aren't as high on the list as the ones Zig does prevent (and C doesn't). It's true that type confusion is also rather high on the list, but Zig clearly reduces type confusion much more than C does.
Nobody denies that Rust prevents more issues than Zig via sound guarantees - albeit at what I think is a significant cost, and we can argue, subjectively, over whether those issues are worth that cost or not - but Zig's guarantees are still closer to Rust's than to C's if eliminating very common/dangerous vulnerabilities is what we're judging by.
It does have a safe subset with respect to spatial memory safety, which is the more important kind of memory safety if what we judge by is dangerous vulnerabilities.
> People might complain about having to fight the borrow checker, but they would complain a lot more if the standard approach to safety-subsetting a language was just bounds-checked array access plus "you can write FORTRAN in any language!"
I don't know how you can say that this is an objectively-supported claim given Rust's poor adoption at its age.
Maybe you and I have different working definitions of "relative", but Rust hit 1.0 only 10 years ago, whereas the age of the most popular languages is 30+ years. In that sense Rust is relatively young. Indeed, Rust is the youngest language in the TIOBE top 20, and it's more popular than other languages which have been around much longer. The only language which comes close is Swift, and that one had the advantage of Apple pushing it as the main language for iOS development, Rust never had that kind of marketing and corporate support.
Edit: just to add some more anecdotal evidence from my memory of languages I used: java community was pretty bigger than rust at 10. Go's was much smaller than rust at 10. I'd be happy to check my beliefs against actual data :)
I agree that of all popular languages, Python is the latest bloomer, but while it became popular for applications and data processing rather late, it was used a lot for scripting well before then.
> Go's was much smaller than rust at 10
Go turned 10 (if we want to count from 1.0) only 3 years ago, and Go's adoption in 2022 was much bigger than Rust's today.
It's true that not many languages that seemed a reasonable choice at the time survived to this day as reasonable choices.
There's no way that can be true.
But I don't think the comparison you're trying to make works, because then isn't now.
In general, in order to convince someone to leave their current tools, you have to not only be better but a lot better. As in, you need to offer the entire feature set of the old tool plus something else compelling enough to overcome the network effects (ecosystem + years of experience + job prospects) of the prior environment.
So when C++ came on the scene, they had to compete against ~20 years of accumulated legacy systems and language history. Rust had to compete with 50 years of legacy systems and language history.
Moreover, developer expectations are a lot different today. Back then, C++ was what, a compiler and some docs? Python was an interpreter and some docs? Maybe an IRC channel? Today, it's not enough to reach 1.0, you also have to deliver a package manager, robust 3rd party library ecosystem, language server tooling, a robust community with support for new devs, etc. So timescales for language development are getting longer than they were back then.
Also, I don't know why you've chosen "very popular" as a metric. Very popular isn't something a language needs to be, it just needs to be big enough to sustain a community. Being top 20 within 10 years is certainly in that realm. You can see that other language communities have existed for longer and are much smaller. And anyway, the entire developer population today is much larger than it was back then; you can have a small percentage of all developers but still large enough to be robust. I don't know the math, maybe someone can figure it out, but I wouldn't be surprised if 1% of developers today is inflation adjusted to like 10%-20% of developers in 1996. So Rust is probably as big as it needs to be to sustain itself, it doesn't have to be a "very popular" language if that means being in the top 5 or whatever the threshold is.
It's very popular compared to Prolog or Haskell, but not compared to languages people use professionally: https://www.devjobsscanner.com/blog/top-8-most-demanded-prog...
> In general, in order to convince someone to leave their current tools, you have to not only be better but a lot better.
I agree.
> So when C++ came on the scene, they had to compete against ~20 years of accumulated legacy systems and language history. Rust had to compete with 50 years of legacy systems and language history.
Ok, but Go and TypeScript are pretty much the same age, and when Java came out, it took over much of C++'s market very quickly.
I agree Rust has some clear benefits over C++, but it also has intrinsic challenges that go well beyond mere industry momentum (and other languages have shown that momentum is very much defeatable).
> Moreover, developer expectations are a lot different today.
But there are more programmers today, and many more people worked on Rust than on C++ in its early years. And besides, Rust has had all those things you mentioned for quite some time, and C++ still doesn't have some of them.
> Also, I don't know why you've chosen "very popular" as a metric. Very popular isn't something a language needs to be, it just needs to be big enough to sustain a community.
I agree it doesn't need to be very popular to survive. But popularity is a measure of the actual benefit a language brings or, at least, lack of popularity is a measure of lack of sufficient benefit, because software is a competitive business. So claims that Rust is some huge game-changer don't really square with its rate of adoption.
I think that's the end of it then, yeah? We've established it's popular enough (you set a lower bound at Haskell, which has been around for 35 years, has an active and vibrant community, and is still used in industry), we agree it doesn't need to be more popular, so then this threshold of "very popular" you invented (which I guess is the top 10) is arbitrary and therefore not relevent.
> Ok, but Go and TypeScript are pretty much the same age, and when Java came out, it took over much of C++'s market very quickly.
These two languages were created and pushed by two of the largest corporations on the planet. Typescript is basically Javascript++, and it came at a time when Javascript was to a large degree the only language for the browser. So they had: 1) one of the largest corporations in the world backing it with effectively unlimited money as part of a larger campaign to win web developer mindshare 2) a large developer base of people who already spoke the language 3) guaranteed job opportunities (at least at Microsoft, so more quickly followed) for people who invested in it. Microsoft was also instrumental in defining the platform on which Typescript ran, so they had that benefit as well. That's one way to achieve success for a language, but it requires only offering a very small delta in features; Typescript could only do what it did by being Javascript + types.
Likewise with Go, they bootstrapped that community with Googlers. Bootstrapping a community is way harder than bootstrapping a language, so having a built-in community is quite an advantage. People wanted to learn Go just to have it on their resume, because they heard it would help them land a job there. Plenty of my students took that route. Google threw their weight around where they could for Go, even going as far as to steal the name right out from another language developer and telling him to pound sand when he complained about it.
I mean, Google could afford to hire Robert Griesemer, Rob Pike, AND Ken Thompson to create Go; whereas Rust came from the side project of a lowly Mozilla software engineer. We're looking at two very different levels of investment in these respective languages.
This seems to me like cherry picking. You're taking the best-case scenarios and then comparing it to something not like that at all. When it pales in comparison, you conclude it's not sufficient. But here's the thing: if we want programming as a field to evolve, not every new language can be ExistingLang++. Some languages are going to have to take big swings, and they're not going to be as popular as the easy road (big swings mean big divisions and polarized views; Javascript + types is an easy and agreeable idea). That doesn't mean they aren't just as if not more beneficial to programming languages as a field.
> But there are more programmers today, and many more people worked on Rust than on C++ in its early years.
Yes, and that completely muddles your point, which is why these comparisons don't make sense. It's like comparing the success of a new NFL team to teams from 50 years ago. Yeah they're ostensibly playing the same game but in many important ways they're actually not.
So at best in order to make the claim you're trying to make, you'd have to normalize the data from then and now. You haven't done that so you can't say Rust hasn't achieved arbitrary threshold of popularity after 10 years and therefore... I'm not exactly sure what your conclusion is actually. Therefore it won't survive? Therefore it's not all people make it out to be? I don't know, you're not being clear.
> But popularity is a measure of the actual benefit a language brings or, at least, lack of popularity is a measure of lack of sufficient benefit
If you're going to make this claim you've gotta back it up with some data. "popular", "actual benefit", "sufficient benefit" are all fuzzy words that mean one thing in your head but mean something different in everyone else. Many people live long enough to understand "popular" and "best" are not often synonymous.
> So claims that Rust is some huge game-changer don't really square with its rate of adoption.
Did anyone make that claim here? Rust is programming language like any other, and at best it's an incremental improvement over current languages, just like all of the top new languages of the last 50 years. The closest thing to a "game changer" I've seen is LLM vibe coding, but otherwise the game in Rust is the same as it's always been: 1) press keyboard buttons to write code in text buffer, 2) compile, 3) dodge bugs, 4) goto 1. Rust makes the first and second parts marginally worse, while making the third part marginally better. It doesn't change the game, but it makes it more fun to play (IMO).
I don't think Rust lacks in hype and marketing. It doesn't buy ads in print magazines, but no language does anymore (that's exactly how VB, Delphi, FoxPro, Visual C++, and Java were marketed). And don't forget that while being well-known is necessary for success, it's far from sufficient.
There's also the matter that large corporations may let certain star personalities work on vanity projects, they tend not to invest too heavily in projects they think are unlikely to succeed. In other words, even corporations can't market their path to success, at least not for long. That's why they try to market the things they already believe have a chance of success. Sun acquired technologies developed for Smalltalk and diverted them to Java because they believed Java had a better chance of success.
> This seems to me like cherry picking
Quite the opposite, I think. I can't find a single example of a language with Rust's adoption at age 10 that ended up very popular.
> whereas Rust came from the side project of a lowly Mozilla software engineer
So did C++.
> If you're going to make this claim you've gotta back it up with some data.
I'm backing it up with the market and the idea that in a highly competitive market, any technology that carries a significant competitive advantage in shorter time-to-market or in better reputation etc. should be picked up - at least if it is well-known. It's the claim that a technology gives its adopter a competitive advantage and yet doesn't spread as quickly as previous similar technologies that requires explanation.
> Did anyone make that claim here?
This whole debate is over whether Rust has some "superabled" and unique bottom-line-affecting capabilities compared to Zig.
> Rust is programming language like any other, and at best it's an incremental improvement over current languages
If you see Rust as one avenue for incremental improvement over C++, then we're in complete agreement :)
https://archive.gyford.com/1997/wired-uk/1.08/features/java....
And the rest of those basically had no competition in their domain when they started 30+ years ago. Rust now has to grow next to 30 years of those languages maturing, and convince people to abandon all existing community resources - whereas those languages did not.
Having a low adoption rate is normal in this day and age. Go is kind of an anomaly caused by it's backing by Google.
But it doesn't help that Rust is also in the native space, whose devs are especially stubborn, and is a difficult language with painful syntax.
That's not true, as anyone who was programming back then (like me) knows. Java had serious competition from VB, Delphi, and a host of other "RAD" languages as they were called back then (and not long before, the language that the magazines were touting as "the future" was Smalltalk). All of them were heavily marketed. C++, of course, had to compete against an established incumbent, C, and another strong contender, Ada (Ada, BTW, was about as popular in 1990, when it was 10 years old, as Rust is today, although bigger, more important software projects were being written in Ada in 1990 than are being written in Rust today). Python and Ruby both were both competing with the very powerful incumbent, Perl. PHP, of course, had Java to compete with, as did C#. Some of these languages had strong backers, but some started out as very small operations (Python, C++, PHP), and some languages with very strong backers did poorly (Delphi, FoxPro).
Again, I have no idea if Rust will ever really take off, but its adoption at this advanced age, despite no lack of marketing, would be extraordinarily low for a language that becomes very popular.
> But it doesn't help that Rust is also in the native space, whose devs are especially stubborn
Perhaps, but Fortran, C, and C++, were all in this space and they all spread rather quickly. Microsoft, a company with a fondness for complicated languages, chose to write significant portions of their flagship OS in C++ when the language was only five years old.
It's true that the market share of low-level languages has been shrinking for several decades now and continues to shrink, but also isn't really a good news for a language that for at least a decade has been trying to get a significant share of that shrinking market, and has been having a hard time at that.
> and is a difficult language with painful syntax.
Yes, but this, too, isn't a point in favour of betting on Rust's future success. Other difficult or complex languages indeed had a harder time getting much adoption in their first decade, but things also didn't pick up for them in their second decade.
The latest bloomer of the bunch is Python, but if Rust ever becomes very popular (even as popular as C++ is today), it would need to break Python's record. That's not impossible, but it would be highly unusual. Low adoption in the first decade has virtually always been a predictor of low adoption down the line, too.
Of course it's subjective, but I think there is a perception of perceived benefit over effort. Zig gives much perceived benefit over low effort. Rust gives much perceived benefit over more effort. Even more effort for ATS. But the benefit is relative: nobody cares to create totally bug-free software when the software is not critical at all. In addition, most programmers think that solving bugs is part of the job more than preventing them. Solving segfaults is often easier than thinking about formal systems, so the perceived benefit is higher in Zig than ATS - at least for programmers that know C, pointers and the like. Note how the majority of programmers don't deal with memory allocations at all: they use JavaScript and Python, memory is managed. For them, solving memory bugs is not something that makes sense, so the effort of dealing with memory is enough to renounce that freedom altogether. Rust is a very good middle ground: it's a complex language, but there's lot of room for improving its ergonomics.
I certainly agree Rust is a much better middle ground than either C or ATS. But so is Zig. What's harder to support objectively is that Rust is a better middle ground than Zig (or vice-versa). We just don't know! They both make different tradeoffs that we can't objectively rule on.
So all I'm saying is that we're left with subjective preferences, and that's fine, because that's all we have! So let's stick to saying "I like Rust's design better" or "I like Zig's design better", and stop trying to come up with objective reasons that are just not well-founded.
At the very least, people should stop comparing Zig to C as part of an argument that claims Rust is good because it prevents the vulnerabilities associated with memory-safety violations, as Zig prevents the most dangerous of those, too.
I can see another language having a more expressive type system, I've come up against the limitations of Rust's type system more than once, but the tradeoff isn't worth it if I have to go 20 years back in time in terms of tooling.
BTW, I'm not saying Rust is bad. All I'm saying is that the attempt at proving it's objectively best by leaning on memory-safety is not really as objective as the people who make that claim seem to think it is.
I'm looking for the next thing I want to learn, and have been leaning towards logic programming and theorem provers, so you inadvertently piqued my interest.
What are we measuring? Lines of code? Number of programmers employed? Number of new applications started?
Rust is in: Linux, Windows, Azure, all over AWS, Amazon's Prime video, Cloudflare's proxy, Firefox, Python's `cryptography` package, Zed editor. This is just the sample I know of.
Is this low adoption?
They're correlated, but number of programmers employed is something that's relatively easy to measure.
> Is this low adoption?
For a language this old? Yes. That people talk so much about specific projects that use Rust only underlines that: Rust is now as old as Java was when JDK 6 came out; older than PHP was when PHP 5 came out or Facebook was launched; older than C++ was when Windows NT came out.
How much adoption should we expect Rust to have at this point, and how does it compare to other languages? I certainly don't have the impression that Rust has relatively low adoption in a general sense, although I'm also a fan of the language and make a point of being in programming communities that are interested in Rust too.
Great post on what comptime won't do: https://matklad.github.io/2025/04/19/things-zig-comptime-won...
Which part of expertise is rejecting the fact that safety through professional mind tricks in lieu of better underlying language design is unattainable?
Seconded. I've really come to loathe tech that is constantly trying to "help me" unprompted and do things I didn't ask/want it to do or burying settings/configurations if not obfuscating them away entirely and acting as if it's doing me a favor by removing features in the name of "simplicity" or some shit. And let's not forget built-in obsolescence moonlighting with privacy-disrespecting dark patterns masquerading together as "Smart Devices."
This attitude is why we still have bounds checking memory bugs in new software in 2025.
IMHO an artisan should want superior tools that produce better results.
This made me think about Rust borrow checker: given the amount of people struggling with it, I would think the number of experts is much lower than I would initially assume.
It is correct that the hype is past its peak, however, the TIOBE trend (if one wants to use that) is actually steadily increasing.
> There is still some development in linux
"Some development" is a miscarachterization - the official addition to the Linux kernel itself is a very big deal, and its adoption is increasing and will continue to do so.
I think that Rust has found its niche in safe low-level programming, and it will slowly have an increasingly dominant role in (although the ceiling of this area is certainly limited in the global landscape).
I still like it -- for systems programming, that is. It's a much better C++ basically.
Just curious, what language(s) do you prefer for things that you don't classify as "systems programming"?
Once that's over, people start looking at it with a more pragmatic eye - how much better is this really than what I had before. People start focusing less on the gimmicks and more on everyday usability.
For a programming language to be really popular, it needs that something that captures people's imaginations, but ultimately the stay power is determined by how useful it turns out.
Kotlin and Swift are very practical, but never had any wow features, so they never got hyped, they just quietly got more popular. Go had it with its green threads and channels, but nowadays most people seem to be not using those that much (I don't think there are a ton of instances of Go processes in prod with 10k threads), but otherwise its a solid language.
Rust - it's a solid language as well, and an improvement over C++ in some aspects like package management, but it's borrow checker and programming style is divisive.
Thing is, unlike goroutines there's no avoiding the borrow checker, so a lot of people don't really commit to Rust.
Err..this is incorrect. Some projects who scale to 10k go-routines on a single instance regularly are loki and CockroachDB. Even your common NATS server can scale 5k+ go-routines on single instance and it is not uncommon.
Oh, 14th [1]. That's a lot lower than I would have expected, based purely on the amount of noise surrounding Rust.
[1] https://www.tiobe.com/tiobe-index/
But PYPL has shown Objective-C rising to #4 in the last few months....
Rust is targeted at strategically important systems (proxies, databases, OSs, VMs, hypervisors, high-throughput servers, cryptography, browsers) and by any measure is making significant inroads into those kinds of systems in real industrial applications, and I'm to believe that Rust adoption is languishing? Am I going insane?
Rust has a SDK from the 3 big cloud providers, Rust IS mainstream.
Zig is a better C. No abstractions. Close to bare metal.
Rust is a better C++. Abstractions to simplify application level programming.
The reason we care about memory-safety so much, compared to other invariants we'd like our programs to have is because, as the article notes, a very high portion of vulnerabilities are due to memory-safety violations. This is why preventing or reducing such violations is important in the first place.
But if we look at vulnerability rankings [1][2], we see that Zig's memory safety covers the top weaknesses just as well as Rust, and much better than C. The vast difference in the complexity of these two languages is because Rust pays a lot to also prevent less dangerous vulnerabilities, outside the top 5.
So if Rust is good because it eliminates some very common dangerous vulnerabilities thanks to its memory safety, then Zig must also be good for eliminating the same ones. Calling it C-like because it doesn't eliminate some less common/dangerous vulnerabilities just because Rust does, is just a misunderstanding of why this is all important in the first place. (Plus, if it's important to reduce the security vulnerabilities due to memory safety violations, isn't it better to make avoiding the worst outcomes more approachable?)
In software correctness there are few easy choices. Everything boils down to how much you can and should pay to improve your confidence that a certain level of damage won't occur. It's a complicated subject, and trying to present it as a simple one does it a great disservice.
In fact, both Rust and Zig address some of the most common/dangerous vulnerabilities — more than use-after-free - just as well as C, which is to say, not, or barely, at all. I.e. there are worse vulnerabilities that neither one of them eliminates than the ones Rust eliminates and Zig doesn't.
There is no doubt that Rust and Zig are meant to appeal to people with different aesthetic preferences, but the attempt to distinguish them by turning the matter of memory-safety into a binary one simply doesn't make sense. The property of memory safety is itself not binary in both languages, and the impact of memory safety is split between more and less important effects.
I understand why people wish to find objective metrics to prefer one language over another, but often such metrics are hard to come by, and extrapolation based on questionable assumptions is not really objective.
But if you choose to only focus on security weaknesses, and you choose to ignore the language design's impact on code reviews or the fact that allocations are much more visible in Go than in C (which is not very objective, but perhaps you consider these harder to quantify), you would still have to conclude that there's a big difference - on your chosen metric alone - between Zig and C, and a rather small difference between Rust and Zig.
What I think really happens, though, is that most of the preference boils down to aesthetics, and then we desperately seek some objective measures to rationalise it.
> Much of Zig seems to me like "wishful thinking"; if every programmer was 150% smarter and more capable, perhaps it would work.
But if working harder to satisfy the compiler is something that requires less competence than other forms of thinking about a program, then why Rust? Why not ATS? After all, Rust does let you eliminate more bugs at compile time than Zig, but ATS lets you eliminate so many more. So, if this is an objective measure to reject Zig in favour of Rust, then it must also be used to reject Rust in favour of ATS.
Neither Rust nor Zig are anywhere near either extreme on compile-time guarantees in general and memory-safety in particular. They're closer to each other on the spectrum than either one of them is to either C or ATS. They both compromise heavily. It's perfectly fine to prefer one compromise over the other, but to a measure that would settle which of these compromises is objectively better is just not something we have at this time.
[1]: https://cwe.mitre.org/top25/archive/2024/2024_cwe_top25.html
[2]: https://cwe.mitre.org/top25/archive/2024/2024_kev_list.html
But once you've taken care of the top weaknesses, it becomes harder to justify putting more effort into eliminating some weaknesses that could go into reducing more common/dangerous ones. If vulnerabilities are the justification, it definitely makes more sense to reduce, say, #4 on the list than #7.
But Zig does not eliminate them, but rather it might catch them at runtime. The difference here is that Rust promises that it will detect them at compile time, long before I ship my code.
> The property of memory safety is itself not binary in both languages
In this case it is: either you catch the issue at compile time, or you don't. This is the same as type safety: just because Python can detect type errors at runtime it does not mean that it's as "type safe" as, for ex. Haskell. This might be due to imprecise usage of terms but that's just the way it's discussed in the craft.
So does Rust. That's what we mean by eliminating them. Zig/Rust will panic, but you won't get a vulnerability.
> The difference here is that Rust promises that it will detect them at compile time, long before I ship my code.
No, Rust doesn't guarantee catching spatial-memory-safety violations at compile-time. Neither do Java, Python, or JS/TS, by the way.
The exact positioning within the top 10 is also quite noisy: if you look at last year's list, UAF is in the #1 spot for actively exploited vulnerabilities, even beating out all the web ones: https://cwe.mitre.org/top25/archive/2023/2023_kev_list.html
Lastly, filtering on CVEs has a high selection bias: just because security researchers go for the easy vulnerabilities first doesn't mean that the harder ones can be ignored. As high-profile projects adopt tooling and mitigations to reduce the impact of spatial memory safety problems, it's common to see a sudden increase in CVEs related to temporal memory safety. This is not because use-after-free bugs somehow became more common or severe -- it's because once you eliminate the easy source of vulnerabilities, the attackers shift their attention to the new lowest-hanging fruit.
The point isn't about limiting to the top 5. The point is that once you get to the things Rust prevents and Zig doesn't, there are quite a few more things that neither prevents, so it's just silly to draw a a particular sharp line between Rust and Zig because they perform exactly the same (in terms of sound guarantees; we're ignoring any softer effects) for most top weaknesses.
Even if you think that difference is so important that it justifies downsides that Rust may have in comparison, you still have to admit that Zig is much, much closer to Rust than to C by that measure.
And this "closer" matters because Rust's memory safety is also not absolute, and Rust proponents must accept that the cost of memory safety is an important factor, too, and sometimes not worth it, or else Rust wouldn't have been invented in the first place. After all, languages that are as memory-safe as Rust and more were more popular than Rust will ever be before it was even invented.
So Rust proponents must accept that eliminating dangerous vulnerabilities is good (unlike C), that productivity and cost do matter (unlike ATS), and that non-absolute memory safety is acceptable. And Zig satisfies all of these points, too.
The reason it's hard to find an objective metric to draw the line between Rust and Zig is because they're actually quite close to each other, at least on this front of trying to find a useful compromise between productivity and guarantees.
> Lastly, filtering on CVEs has a high selection bias: just because security researchers go for the easy vulnerabilities first doesn't mean that the harder ones can be ignored.
Sure, but then you might as well also consider softer effects. For example, maybe a language that's easier to review because it's more explicit, or a language that's faster to compile and is easier to test wins.
And I agree that we should consider all these, but then we start seeing why correctness is such a complicated topic, and we could speculate just as easily that it is Zig that "clearly" wins.
Anyway, it's perfectly fine for people to prefer Rust because they like it. But the attempt to find objective reasons for this preference is not based on any truly objective foundations, and just looks like some desperate rationalisation.
And BTW,
> relevant to applications that would typically be written in C/C++/Rust/Zig
If you think that Rust and Zig are designed to target the exact same domains, then some of the "softer" aspects I mentioned could play even a larger role. I mean, the portion of software written in low level languages has been declining steadily for a long time with no sign of a change in the trend. To me it seems that Zig has internalised the narrower and more focused and role of low-level languages today compared to what C++ imagined it would be in the eighties.
There is a very clear sharp line between them in that Rust has no undefined behavior outside of an unsafe block. This matters because the effects of undefined behavior -- particularly memory-corrupting undefined behavior -- are unbounded. Security issues caused by logic bugs are limited to only having local effects on the program -- a SQL injection bug can lead to the wrong SQL query being executed, a path traversal bug can lead to the wrong path being accessed, and a shell escaping bug can lead to execution of the wrong shell command. These are severe problems that can lead to data exfiltration or remote code execution, but the relationship between bug and effect is straightforward: "I'm passing user input to a shell here; this could have catastrophic consequences so I'd better review this carefully." In contrast, undefined behavior can happen anywhere in your program, and it can do anything. That is a clear and measurable difference, and emperical evidence from the last 10 years clearly indicates both that it is nigh impossible to write large C/C++ applications without both spatial and temporal memory safety vulnerabilities, and that adopting Rust measurably decreases the incidence of such vulnerabilities.
Zig is certainly an improvement over C on this front, but it is still a UB-heavy language, and that's where the sharp line is. It's hard to make emperical comparisons because Zig is so young, but the comparision between Deno and Bun in the article is a reasonably strong demonstration that Zig has not achieved a comparable level of memory safety to Rust.
> Sure, but then you might as well also consider softer effects. For example, maybe a language that's easier to review because it's more explicit, or a language that's faster to compile and is easier to test wins.
> And I agree that we should consider all these, but then we start seeing why correctness is such a complicated topic, and we could speculate just as easily that it is Zig that "clearly" wins.
This doesn't really have anything to do with my point that the CVE list does not provide evidence to dismiss temporal memory safety as irrelevant; it's more of a general statement on writing correct software. But regardless, "Zig has nullability and bounds checks" and "Rust has an affine type system, statically-checked immutability and exclusivity, language-level resource management, and no undefined behavior" are not in the same league of program correctness. Rust wasn't designed after some ideal of memory safety at the expense of clarity and correctness: the lifetime and type system came from a goal of reducing logic bugs in complex concurrent programs, and the fact that it is powerful enough to achieve memory safety without garbage collection was a happy accident. The emperical results that Rust programs have fewer memory-safety vulnerabilities demonstrate that Rust's static approach to software correctness is successful, and not just for the specific problem of memory safety, because Rust's tooling for achieving program correctness is generalizable to arbitrary application invariants. This lines up with my own experience; software I write using Rust is far easier to get right, more reliable, and easier to successfully maintain and refactor than anything else I've done.
Certainly Zig has its strong points as well -- explicitness can reduce complexity and compile times, but it also has downsides of pushing complexity into application code (thus making it harder to review and introducing more opportunities to create mistakes). A proper comparison of the two approaches is worthwhile, but just as "Rust is more memory safe" is an overly reductive generalization of the langauges' approach to software correctness, "there's a rather small difference between Rust and Zig" simply isn't true.
Yes, but that's an intrinsic language feature whose value needs to be justified somehow. If you justify it by saying it prevents dangerous vulnerabilities, we're back to my point.
> This matters because the effects of undefined behavior -- particularly memory-corrupting undefined behavior -- are unbounded...
While I appreciate this explanation (and I've seen it many times), I hope you understand that it's more speculative and subjective than an empirical finding. At the end of the day, to measure the danger of a problem, we need to see what the actual vulnerabilities/exploits are and how common they are. Clearly, not all undefined behaviours are equally exploitable. That's why we see differences in weakness severity among different kinds of UB.
> emperical evidence from the last 10 years clearly indicates both that it is nigh impossible to write large C/C++ applications without both spatial and temporal memory safety vulnerabilities
Right, and that same empirical evidence shows that spatial violations are the more dangerous ones, and that's exactly why Zig prevents them.
> but the comparision between Deno and Bun in the article
What article? It seems that Bun has had one CVE. If you're talking about undefined behaviour you're, again, making an unjustified extrapolation from it to security. Some undefined behaviour leads to easily exploitable vulnerabilities, some does not.
It's true that in the presence of UB, the compiler could hypothetically do anything, but to get a dangerous vulnerability it has to actually do something that's exploitable, and when we look at vulnerabilities caused by UB, we see that some kinds are more dangerous than others because of that.
BTW, this touches on something that is sometimes misunderstood about UB. UB is defined with respect to a language specification, i.e. in the presence of UB, the language specification does not assign a program a meaning, but the compiler certainly does, because machine code has no UB. The program with the UB needs to compile to an exploitable binary for a vulnerability to exist.
> and that's where the sharp line is
I agree it's a sharp intrinsic line, just as saying that Zig avoids macros is a sharp line, but the impact of that line is anything but sharp. To draw the practical conclusion from it you don't follow the findings, but ignore them!
> This doesn't really have anything to do with my point that the CVE list does not provide evidence to dismiss temporal memory safety as irrelevant
I wasn't dismissing it as irrelevant. I was saying that if Rust's value is in eliminating dangerous vulnerabilities, then Zig has that value, too, and the difference between them isn't large on that particular front.
> are not in the same league of program correctness
Software correctness is something I've been dealing with and writing about for many years, especially formal verification (https://pron.github.io), and I can tell you that you're downright wrong on that. That "more sound guarantees is always the most effective form of improving correctness" is something we know (at least since the nineties) not to be generally true, which is also why the field is looking more and more into unsound methods. For example, Rust and Zig are more likely to effectively write correct programs than ATS, even though ATS is "in a different league" from both of them when it comes to sound guarantees.
We know that sound guarantees can help, but that their cost matters a lot. We also know that reviews and tests and dynamic verification are very effective, sometimes more than sound guarantees.
Rust proponents are free to speculate that, ultimately, Rust's approach leads to more correctness than Zig, and they can base that belief on some findings, and Zig proponents can do exactly the same in the opposite direction, also based on other findings, but both are speculations. People are free to choose which they are more inclined to believe, but the question isn't settled.
> This lines up with my own experience; software I write using Rust is far easier to get right, more reliable, and easier to successfully maintain and refactor than anything else I've done.
I'm not doubting that that's your experience. I'm saying we have no evidence that it's universal, likely to be universal etc. (and I know of some opposite experiences with Rust). Sometimes certain languages just click with certain people, but we can't extrapolate without more observation.
> "there's a rather small difference between Rust and Zig" simply isn't true.
The correctness difference between the two is unknown. It could be small or large and in either direction. The intrinsic differences are, of course, known, but don't really help reach an objective preference. My point was only that if we judge Rust by the vulnerabilities it soundly eliminates, then Zig is not far on that particular metric, and it's certainly much closer to Rust than to C.
And remember that a software system, unlike an abstract algorithm, is a physical system that cannot be proven correct, since the behaviour of the physical hardware cannot be proven. We're always dealing in probabilities, and so the question is: how do we get the most value (in terms of reducing the probability of costly bugs) for a unit of effort.
Since the 1970s, the size of software that can be proven correct in practice using deductive methods has only fallen compared to the average size of a program (i.e. the size of acceptably-reliable software we write has grown much more rapidly than the size of software we can prove correct using deductive methods). The largest programs ever proven correct using deductive methods are on the order of 10KLOC.
So the field of software correctness has long ago abandoned the position (held by some in the 70s) that proof is always the most effective way toward correctness.
[1]: https://gwern.net/doc/math/1996-hoare.pdf
I don't really think much of Zig myself for other reasons, but comptime seems like a good design.
The point is that certain casts/type conversions can change the underlying data.
> like the int with value 3 landing in memory after calling atoi("3").
That's something else entirely. People may colloquially call this "converting a string to an integer", but what we're realling doing here is parsing a string as an integer.
Is that the case? That's not what I think of when I think of C-style casts.
The representation in memory of `val` should not match that of `val_i`, right? The value is encoded differently and the quantity is not preserved through this transformation. I don't think that means that the data weren't changed.Maybe you're thinking of aliasing/type-punning? Casts in C do perform conversions as they do in C++.
People think it's a slight on their abilities. "I can write memory safe code!" Maybe you can. There are two huge problems here, and they're problems that will never go away no matter how good you are.
The first is that this doesn't scale. As soon as you add more programmers to a project, you multiply the odds of bugs like this. Even if everyone's just as good, not everyone will have the whole program in their head or code in exactly the same style.
The second is that code rots. Your new C (or Zig) program might be totally correct and memory safe when it's first written. Then you commit it to a repo. Then you move on to another project for a while. Then someone else fixes something and you merge a PR. Then you come back to it three months later and you're under pressure to implement something. Then you work in a new feature a year later and you've forgotten some of the really nit-picky details of how things work. It's very easy over time for bugs to creep in, and if the language doesn't catch them they'll sit in the code until they cause random crashes or, worse, a CVE.
These aren't avoidable issues. They're inherent to software and its life cycle. Memory safe languages (and secure computing systems in general) are the only way to deal with them.
This statement, albeit true, is highly misleading. In the example given, you ought to be concerned with parallel assignments not parallel moves. See [0] for more details on the distinction.
[0] https://inria.hal.science/inria-00289709
20 more comments available on Hacker News