16 ms·
Thoughts on Go vs. Rust vs. Zig
- reeeli 11mo agoif the languages were creations of LLMs, what would be your (relatively refined) chain(s) of (indulgently) critical thought?
- echelon 11mo ago> Many people seem confused about why Zig should exist if Rust does already. It’s not just that Zig is trying to be simpler. I think this difference is the more important one. Zig wants you to excise even more object-oriented thinking from your code. I feel like Zig is for the C / C++ developers that really dislike Rust. There have been other efforts like Carbon, but this is the first that really modernizes the language and scratches new itches. > I’m not the first person to pick on this particular Github comment, but it perfectly illustrates the conceptual density of Rust: [crazy example elided] That is totally unfair. 99% of your time with Rust won't be anything like that. > This makes Rust hard, because you can’t just do the thing! You have to find out Rust’s name for the thing—find the trait or whatever you need—then implement it as Rust expects you to. What? Rust is not hard. Rust has a standard library that looks an awful lot like Python or Ruby, with similarly named methods. If you're trying to shoehorn some novel type of yours into a particular trait interface so you can pass trait objects around, sure. Maybe you are going to have to memorize a lot more. But I'd ask why you write code like that unless you're writing a library. This desire of wanting to write OO-style code makes me think that people who want OO-style code are the ones having a lot of struggle or frustration with Rust's ergonomics. Rust gives you everything OO you'd want, but it's definitely more favorable if you're using it in a functional manner. > makes consuming libraries easy in Rust and explains why Rust projects have almost as many dependencies as projects in the JavaScript ecosystem. This is one of Rust's superpowers !
- unshavedyak 11mo agoRust is hard in that it gives you a ton of rope to hang yourself with, and some people are just hell bent on hanging themselves. I find Rust quite easy most of the time. I enjoy the hell out of it and generally write Rust not too different than i'd have written my Go programs (i use less channels in Rust though). But i do think my comment about rope is true. Some people just can't seem to help themselves.
- nicoburns 11mo agoThat seems like an odd characterization of Rust. The borrow checker and all the other type safety features, as well as features like send/sync are all about not giving you rope to hang yourself with.
- unshavedyak 11mo agoThe rope in my example is complexity. Ie choosing to use "all teh features" when you don't need or perhaps even want to. Eg sometimes a simple clone is fine. Sometimes you don't need to opt for every generic and performance minded feature Rust offers - which are numerous. Though, i think my statement is missing something. I moved from Go to Rust because i found that Rust gave me better tooling to encapsulate and reuse logic. Eg Iterators are more complex under the hood, but my observed complexity was lower in Rust compared to Go by way of better, more generalized code reuse. So in this example i actually found Go to be more complex. So maybe a more elaborated phrase would be something like Rust gives you more visible rope to hang yourself with.. but that doesn't sound as nice. I still like my original phrase heh.
- 1313ed01 11mo agoI would love to see a language that is to C what Rust is to C++. Something a more average human brain like mine can understand. Keep the no-gc memory safety things, but simplify everything else a thousand times. Not saying that should replace Rust. Both could exist side by side like C and C++.
- wtetzner 11mo agoI'm curious about what you'd want simplified. Remove traits? What other things are there to even simplify if you're going to keep the borrow checker?
- 1313ed01 11mo agoI'm the last person to be able to answer that. There would be Chesterton's fences everywhere for one thing. Better question is what to add to something like C. The bare minimum to make it perfectly safe. Then stop there.
- awesome_dude 11mo ago> Rust is not hard. Rust has a standard library that looks an awful lot like Python or Ruby, with similarly named methods. > If you're trying to shoehorn some novel type of yours into a particular trait interface so you can pass trait objects around, sure. Maybe you are going to have to memorize a lot more. But I'd ask why you write code like that unless you're writing a library. I think that you are missing the point - they're not saying (at least in my head) "Rust is hard because of all the abstractions" but, more "Rust is hard because you are having to explain to the COMPILER [more explicitly] what you mean (via all these abstractions) And I think that that's a valid assessment (hell, most Rustaceans will point to this as a feature, not a bug)
- torben-friis 11mo agoOne question about your functional point: where can I learn functional programming in terms of organization of large codebases? Perhaps it is because DDD books and the like usually have strong object oriented biases, but whenever I read about functional programming patterns I’m never clear on how to go from exercise stuff to something that can work in a real world monolith for example. And to be clear I’m not saying functional programming is worse at that, simply that I have not been able to find information on the subject as easily.
- myaccountonhn 11mo agoThere are a lot of lectures/speeches by the creator of elm and Richard Feldman that talk about how to think "functionally" Here is one about how to structure a project (roughly) https://youtube.com/watch?v=XpDsk374LDE https://youtube.com/watch?v=XpDsk374LDE I also think looking at the source code for elm and its website, as well as the elm real world example help a lot.
- simonmic 11mo agoThis seems good: https://www.youtube.com/watch?v=WRoYKBXWJes https://www.youtube.com/watch?v=WRoYKBXWJes
- the__alchemist 11mo agoSame. Zig's niche is in the vein of languages that encourages using pointers for business logic. If you like this style, Rust and most other new languages aren't an option.
- bnolsen 10mo agoThis confuses me. In zig null pointers are illegal, and I have yet to run into any case that should be addressed by using pointer arithmetic, that's all taken care of with slices.
- meepmorp 10mo agoSeems like it's just a comment written by someone with little to no experience using zig.
- tiltowait 11mo ago> Rust has a standard library that looks an awful lot like Python or Ruby, with similarly named methods. Can you elaborate? While they obviously have overlap, Rust's stdlib is deliberately minimal (you don't even get RNG without hitting crates.io), whereas Python's is gigantic. And in actual use, they tend to feel extremely different.
- Yoric 11mo ago> I feel like Zig is for the C / C++ developers that really dislike Rust. Also my feeling. Writing this as a former C++ developer who really likes Rust :)
- Quothling 11mo ago> Rust is not hard. Rust has a standard library that looks an awful lot like Python or Ruby, with similarly named methods. I would read this in regard to Go and not so much in regards to Zig. Go is insanely productive, and while you're not going to match something like Django in terms of delivery speed with anything in Go, you almost can... and you can do it without using a single external dependency. Go loses a little of this in the embeded space, where it's not quite as simple, but the opinonated approach is still very productive even here. I can't think of any language where I can produce something as quickly as I can in Go with the use of nothing but the standard library. Even when you do reach for a framework like SQLC, you can run the external parts in total isolation if that's your thing. I will say that working with the interoperability of Zig in our C for Python binaries has been very easy, which it wasn't for Rust. This doesn't mean it's actually easier for other people, but it sure was for me. > This is one of Rust's superpowers ! In some industries it's really not.
- 999900000999 11mo agoRust is hard because it's just difficult to read. If you know Java, you can read C#, JavaScript, Dart, and Haxe and know what's going on. You can probably figure out Go. Rust is like learning how to program again. Back when I was young and tried C++, I was like this is hard and I can't do this. Then I found JavaScript and everything was great. What I really want is JS that complies into small binaries and runs faster than C. Maybe clean up the npm dependency tree. Have a professional commite vet every package. I don't think that's possible, but I can dream
- ModernMech 11mo ago> This desire of wanting to write OO-style code makes me think that people who want OO-style code are the ones having a lot of struggle or frustration with Rust's ergonomics. I believe this is actually a significant source of consternation. I teach Rust to students, and I find those without a C/C++ background take to it more naturally than those who have a lot of experience with those languages. People with a C/C++ background approach Rust like C/C++ and fight it the whole way, whereas people without that background approach Rust as Rust, and they have a better time with it.
- 0x457 11mo ago[flagged]
- dmoy 11mo agoFor a lot of stuff what I really want is golang but with better generics and result/error/enum handling like rust.
- mixedCase 11mo agoOCaml is the closest match I'm aware of.
- evanmoran 11mo agoI thought the recent error proposal was quite interesting even if it didn't go through: https://github.com/golang/go/issues/71528 https://github.com/golang/go/issues/71528 My hope is they will see these repeated pain points and find something that fits the error/result/enum issues people have. (Generics will be harder, I think)
- Rikudou 11mo agoDidn't they say they're not accepting any new proposals for error handling? I kinda got used to it eventually, but I'll never ever consider not having enums a good thing.
- pa7ch 11mo agoI was a big fan of the original check handle proposal: https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling-overview.md https://go.googlesource.com/proposal/+/master/design/go2draf... I see the desire to avoid mucking with control flow so much but something about check/handle just seemed so elegant to me in semi-complex error flows. I might be the only one who would have preferred that over accepting generics. I can't remember at this point because there were so many similar proposals but I think there was a further iteration of check/handle that I liked better possibly but i'm obviously not invested anymore.
- throwaway894345 11mo agoI cautiously agree, with the caveat that while I thought I would really like Rust's error handling, it has been painful in practice. I'm sure I'm holding it wrong, but so far I have tried: * thiserror: I spend ridiculous and unpredictable amounts of time debugging macro expansions * manually implementing `Error`, `From`, etc traits: I spend ridiculous though predictable amounts of time implementing traits (maybe LLMs fix this?) * anyhow: this gets things done, but I'm told not to expose these errors in my public API Beyond these concerns, I also don't love enums for errors because it means adding any new error type will be a breaking change. I don't love the idea of committing to that, but maybe I'm overthinking? And when I ask these questions to various Rust people, I often get conflicting answers and no one seems to be able to speak with the authority of canon on the subject. Maybe some of these questions have been answered in the Rust Book since I last read it? By contrast, I just wrap Go errors with `fmt.Errorf("opening file `%s`: %w", filePath, err)` and handle any special error cases with `errors.As()` and similar and move on with life. It maybe doesn't feel _elegant_, but it lets me get stuff done.
- gaanbal 11mo agoOP tried zig last and is currently most fascinated by it
- skywhopper 11mo agoWow, this is a really good writeup without all the usual hangups that folks have about these languages. Well done!
- raggi 11mo agoI really hate the anti-RAII sentiments and arguments. I remember the Zig community lead going off about RAII before and making claims like "linux would never do this" (https://github.com/torvalds/linux/blob/master/include/linux/cleanup.h https://github.com/torvalds/linux/blob/master/include/linux/...). There are bad cases of RAII APIs for sure, but it's not all bad. Andrew posted himself a while back about feeling bad for go devs who never get to debug by seeing 0xaa memory segments, and sure I get it, but you can't make over-extended claims about non-initialization when you're implicitly initializing with the magic value, that's a bit of a false equivalence - and sure, maybe you don't always want a zero scrub instead, I'm not sold on Go's mantra of making zero values always be useful, I've seen really bad code come as a result of people doing backflips to try to make that true - a constructor API is a better pattern as soon as there's a challenge, the "rule" only fits when it's easy, don't force it. Back to RAII though, or what people think of when they hear RAII. Scope based or automatic cleanup is good. I hate working with Go's mutex's in complex programs after spending life in the better world. People make mistakes and people get clever and the outcome is almost always bad in the long run - bugs that "should never get written/shipped" do come up, and it's awful. I think Zig's errdefer is a cool extension on the defer pattern, but defer patterns are strictly worse than scope based automation for key tasks. I do buy an argument that sometimes you want to deviate from scope based controls, and primitives offering both is reasonable, but the default case for a ton of code should be optimized for avoiding human effort and human error. In the end I feel similarly about allocation. I appreciate Zig trying to push for a different world, and that's an extremely valuable experiment to be doing. I've fought allocation in Go programs (and Java, etc), and had fights with C++ that was "accidentally" churning too much (classic hashmap string spam, hi ninja, hi GN), but I don't feel like the right trade-off anywhere is "always do all the legwork" vs. "never do all the legwork". I wish Rust was closer to the optimal path, and it's decently ergonomic a lot of the time, but when you really want control I sometimes want something more like Zig. When I spend too much time in Zig I get a bit bored of the ceremony too. I feel like the next innovation we need is some sanity around the real useful value that is global and thread state. Far too much toxic hot air is spilled over these, and there are bad outcomes from mis/overuse, but innovation could spend far more time on _sanely implicit context_ that reduces programmer effort without being excessively hidden, and allowing for local specialization that is easy and obvious. I imagine it looks somewhere between the rust and zig solutions, but I don't know exactly where it should land. It's a horrible set of layer violations that the purists don't like, because we base a lot of ABI decisions on history, but I'd still like to see more work here. So RAII isn't the big evil monster, and we need to stop talking about RAII, globals, etc, in these ways. We need to evaluate what's good, what's bad, and try out new arrangements maximize good and minimize bad.
- ojosilva 11mo agoFine, but there's a noticeable asymmetry in how the three languages get treated. Go gets dinged for hiding memory details from you. Rust gets dinged for making mutable globals hard and for conceptual density (with a maximally intimidating Pin quote to drive it home). But when Zig has the equivalent warts they're reframed as virtues or glossed over. Mutable globals are easy in Zig (presented as freedom, not as "you can now write data races.") Runtime checks you disable in release builds are "highly pragmatic," with no mention of what happens when illegal behavior only manifests in production. The standard library having "almost zero documentation" is mentioned but not weighted as a cost the way Go's boilerplate or Rust's learning curve are. The RAII critique is interesting but also somewhat unfair because Rust has arena allocators too, and nothing forces fine-grained allocation. The difference is that Rust makes the safe path easy and the unsafe path explicit whereas Zig trusts you to know what you're doing. That's a legitimate design, hacking-a! The article frames Rust's guardrails as bureaucratic overhead while framing Zig's lack of them as liberation, which is grading on a curve. If we're cataloging trade-offs honestly > you control the universe and nobody can tell you what to do ...that cuts both ways...
- ekropotin 11mo agoI pretty new to Rust and I’m wondering why global mutables are hard? At first glance you can just use static variable of a type supporting interior mutability - RefCell, Mutex, etc…
- written-beyond 11mo agoI don't think it's specifically hard, it's more related to how it probably needed more plumbing in the language that authors thought would add to much baggage and let the community solve it. Like the whole async runtime debates
- School-Cotton 11mo ago> I pretty new to Rust and I’m wondering why global mutables are hard? They're not. fn main() { unsafe { COUNTER += 1; println!("COUNTER = {}", COUNTER); } unsafe { COUNTER += 10; println!("COUNTER = {}", COUNTER); } } Global mutable variables are as easy in Rust as in any other language. Unlike other languages, Rust also provides better things that you can use instead.
- publicdebates 11mo agoGood write up, I like where you're going with this. Your article reads like a recent graduate who's full of excitement and passion for the wonderful world of programming, and just coming into the real world for the first time. For Go, I wouldn't say that the choice to avoid generics was either intentional or minimalist by nature. From what I recall, they were just struggling for a long time with a difficult decision, which trade-offs to make. And I think they were just hoping that, given enough time, the community could perhaps come up with a new, innovative solution that resolves them gracefully. And I think after a decade they just kind of settled on a solution, as the clock was ticking. I could be wrong. For Rust, I would strongly disagree on two points. First, lifetimes are in fact what tripped me up the most, and many others, famously including Brian Kernighan, who literally wrote the book on C. Second, Rust isn't novel in combining many other ideas into the language. Lots of languages do that, like C#. But I do recall thinking that Rust had some odd name choices for some features it adopted. And, not being a C++ person myself, it has solutions to many problems I never wrestled with, known by name to C++ devs but foreign to me. For Zig's manual memory management, you say: > this is a design choice very much related to the choice to exclude OOP features. Maybe, but I think it's more based on Andrew's need for Data-Oriented Design when designing high performance applications. He did a very interesting talk on DOD last year[1]. I think his idea is that, if you're going to write the highest performance code possible, while still having an ergonomic language, you need to prioritize a whole different set of features. [1] https://www.youtube.com/watch?v=IroPQ150F6c https://www.youtube.com/watch?v=IroPQ150F6c
- gwd 11mo ago> For Go, I wouldn't say that the choice to avoid generics was either intentional or minimalist by nature. From what I recall, they were just struggling for a long time with a difficult decision, which trade-offs to make. Indeed, in 2009 Russ Cox laid out clearly the problem they had [1], summed up thus: > The generic dilemma is this: do you want slow programmers, slow compilers and bloated binaries, or slow execution times? My understanding is that they were eventually able to come up with something clever under the hood to mitigate that dilemma to their satisfaction. [1] https://research.swtch.com/generic https://research.swtch.com/generic
- librasteve 11mo agoI love this take - partly because I agree with it - but mostly because I think that this is the right way to compare PLs (and to present the results). It is honest in the way it ascribes strengths and weaknesses, helping to guide, refine, justify the choice of language outside of job pressures. I am sad that it does not mention Raku (https://raku.org https://raku.org) ... because in my mind there is a kind of continuum: C - Zig - C++ - Rust - Go ... OK for low level, but what about the scriptier end - Julia - R - Python - Lua - JavaScript - PHP - Raku - WL?
- librasteve 11mo agoI tried to get an LLM to write a Raku chapter in the same vein - naah. Had to write it myself: Raku Raku stands out as a fast way to working code, with a permissive compiler that allows wide expression. Its an expressive, general-purpose language with a wide set of built-in tools. Features like multi-dispatch, roles, gradual typing, lazy evaluation, and a strong regex and grammar system are part of its core design. The language aims to give you direct ways to reflect the structure of a problem instead of building abstractions from scratch. The grammar system is the clearest example. Many languages treat parsing as a specialized task requiring external libraries. Raku instead provides a declarative syntax for defining rules and grammars, so working with text formats, logs, or DSLs often requires less code and fewer workarounds. This capability blends naturally with the rest of the language rather than feeling like a separate domain. Raku programs run on a sizeable VM and lean on runtime dispatch, which means they typically don’t have the startup speed or predictable performance profile of lower-level or more static languages. But the model is consistent: you get flexibility, clear semantics, and room to adjust your approach as a problem evolves. Incremental development tends to feel natural, whether you’re sketching an idea or tightening up a script that’s grown into something larger. The language’s long development history stems from an attempt to rethink Perl, not simply modernize it. That history produced a language that tries to be coherent and pleasant to write, even if it’s not small. Choose Raku if you want a language that let's you code the way you want, helps you wrestle with the problem and not with the compiler.
- librasteve 11mo ago
- throwaway894345 11mo ago> [Go] is like C in that you can fit the whole language in your head. Go isn't like C in that you can actually fit the entire language in your head. Most of us who think we have fit C in our head will still stumble on endless cases where we didn't realize X was actually UB or whatever. I wonder how much C's reputation for simplicity is an artifact of its long proximity to C++?
- kanbankaren 11mo ago30 years in C/C++ here. Give an example of UB code that you have committed in real life, not from blogs. I am genuinely curious.
- jech 11mo ago> Give an example of UB code that you have committed in real life struct foo { ... atomic_int v; ... }; struct foo x; memset(&x, 0, sizeof(x));
- rwbt 11mo agoI don't think it's UB if you init the struct before using it atomically from multiple threads.
- gf000 11mo agoAll the memory safety vulnerabilities, which are the majority of bugs in most C/C++ projects?
- kachapopopow 11mo agoI could never get into zig purely because of the syntax and I know I am not alone, can someone explain the odd choices that were taken when creating zig? the most odd one probably being 'const expected = [_]u32{ 123, 67, 89, 99 };' and the 2nd most being the word 'try' instead of just ? the 3rd one would be the imports and `try std.fs.File.stdout().writeAll("hello world!\n");` is not really convincing either for a basic print.
- von_lohengramm 11mo ago> and the 2nd most being the word 'try' instead of just ? All control flow in Zig is done via keyword
- dwb 11mo agoThese are extremely trivial, to the point that I don’t really know what you’re complaining about. What would expect or prefer?
- kachapopopow 11mo agoit's not about triviality, but why not use what is generally accepted already, why did zig decide to be different?
- int_19h 11mo agoWhat is "generally accepted" though? If you mean C-style declarations, the fact that tools such as https://linux.die.net/man/1/cdecl https://linux.die.net/man/1/cdecl even exist to begin with shows what's wrong with it.
- kachapopopow 11mo ago<auto/type/name> <name/type> (array?) (:)= (value) <fn> <generic> <name>(<type/argument>[:] <type/argument> [(->/:) type] [import/use/using] (<package>[/|:|::|.]<type> | "file") (ok header files are a relic of the past I have to admit that) I tried writing zig and as someone who has pretty much written in every commonly used language it just felt different enough where I kept having to look up the syntax.
- vlovich123 11mo agoRe UB: > The idea seems to be that you can run your program enough times in the checked release modes to have reasonable confidence that there will be no illegal behavior in the unchecked build of your program. That seems like a highly pragmatic design to me. This is only pragmatic if you ignore the real world experience of sanitizers which attempt to do the same thing and failing to prevent memory safety and UB issues in deployed C/C++ codebases (eg Android definitely has sanitizers running on every commit and yet it wasn’t until they switched to Rust that exploits started disappearing).
- qouteall 11mo agoCan you provide the source of "(eg Android definitely has sanitizers running on every commit and yet it wasn’t until they switched to Rust that exploits started disappearing)"?
- vlovich123 11mo agoHere’s the report showing the impact has had on memory vulnerabilities in Rust. I guess you’ll have to take my word that they run sanitizers, I don’t know of any good link summarizing their usage, other than it’s listed in AOSP and has instructions on how to use it. https://security.googleblog.com/2025/11/rust-in-android-move-fast-fix-things.html?m=1 https://security.googleblog.com/2025/11/rust-in-android-move... https://source.android.com/docs/security/test/sanitizers https://source.android.com/docs/security/test/sanitizers
- kibwen 11mo ago> In Rust, creating a mutable global variable is so hard that there are long forum discussions on how to do it. In Zig, you can just create one, no problem. Well, no, creating a mutable global variable is trivial in Rust, it just requires either `unsafe` or using a smart pointer that provides synchronization. That's because Rust programs are re-entrant by default, because Rust provides compile-time thread-safety. If you don't care about statically-enforced thread-safety, then it's as easy in Rust as it is in Zig or C. The difference is that, unlike Zig or C, Rust gives you the tools to enforce more guarantees about your code's possible runtime behavior.
- globalnode 11mo agoso does the rust compiler check for race conditions between threads at compile time? if so then i can see the allure of rust over c, some of those sync issues are devilish. and what about situations where you might have two variables closely related that need to be locked as a pair whenever accessed.
- ViewTrick1002 11mo agoIt entirely prevents race conditions due to the borrow checker and safe constructs like Mutexes. Logical race conditions and deadlocks can still happen.
- globalnode 11mo agoah i see, thanks. i have no idea what rust code looks like but from the article it sounds like a language where you have a lot of metadata about the intended usage of a variable so the compiler can safety check. thats its trick.
- timschmidt 11mo agoThat's a fairly accurate idea of it. Some folks complain about Rust's syntax looking too complex, but I've found that the most significant differences between Rust and C/C++ syntax are all related to that metadata (variable types, return types, lifetimes) and that it's not only useful for the compiler, but helps me to understand what sort of data libraries and functions expect and return without having to read through the entire library or function to figure that out myself. Which obviously makes code reuse easier and faster. And similarly allows me to reason much more easily about my own code.
- Aperocky 11mo agoAnecdotally, as a result of the traits that made it hard to learn for humans, Rust is actually a great language for LLM. Out of all languages I do development in the past few months: Go, Rust, Python, Typescript; Rust is the one that LLM has the least churn/problems in terms of producing correct and functional code given a problem of similar complexity. I think this outside factor will eventually win more usage for Rust.
- damslunk 11mo agoYeah that's an interesting point, it feels like it should be even better than it is now (I might be ignorant of the quality of the best coding agents atm). Like rust seems particularly well suited for an agent based workflow, in that in theory an agent with a task could keep `cargo check`-ing it's solutions, maybe pulling from docs.rs or source for imported modules, and get to a solution that works with some confidence (assuming the requirements were well defined/possible etc etc). I've had a mixed bag of an experience trying this with various rust one off projects. It's definitely gotten me some prototype things working, but the evolving development of rust and crates in the ecosystem means there's always some patchwork to get things to actually compile. Anecdotally I've found that once I learned more about the problem/library/project I'll end up scrapping or rewriting a lot of the LLM code. It seems pretty hard to tailor/sandbox the context and workflow of an agent to the extent that's needed. I think the Bun acquisition by Anthropic could shift things too. Wouldn't be surprised if the majority of code generated/requested by users of LLM's is JS/TS, and Anthropic potentially being able to push for agentic integration with the Bun runtime itself could be a huge boon for Bun, and maybe Zig (which Bun is written in) as a result? Like it'd be one thing for an agent to run cargo check, it'd be another for the agent to monitor garbage collection/memory use while code is running to diagnose potential problems/improvements devs might not even notice until later. I feel like I know a lot of devs who would never touch any of the langs in this article (thinking about memory? too scary!) and would love to continue writing JS code until they die lol
- oncallthrow 11mo ago> Other features common in modern languages, like tagged unions or syntactic sugar for error-handling, have not been added to Go. > It seems the Go development team has a high bar for adding features to the language. The end result is a language that forces you to write a lot of boilerplate code to implement logic that could be more succinctly expressed in another language. Being able to implement logic more succinctly is not always a good thing. Take error handling syntactic sugar for example. Consider these two snippets: let mut file = File::create("foo.txt")?; and: f, err := os.Create("filename.txt") if err != nil { return fmt.Errorf("failed to create file: %w", err) } The first code is more succinct, but worse: there is no context added to the error (good luck debugging!). Sometimes, being forced to write code in a verbose manner makes your code better.
- howenterprisey 11mo agoYou can just as easily add context to the first example or skip the wrapping in the second.
- fragmede 11mo agoyeah but which is faster and easier for a person to look at and understand. Go's intentionally verbose so that more complicated things are easier to understand.
- ux266478 11mo agoGenerally a good writeup, but the article seems a bit confused about undefined behavior. > What is the dreaded UB? I think the best way to understand it is to remember that, for any running program, there are FATES WORSE THAN DEATH. If something goes wrong in your program, immediate termination is great actually! This has nothing to do with UB. UB is what it says on the tin, it's something for which no definition is given in the execution semantics of the language, whether intentionally or unintentionally. It's basically saying, "if this happens, who knows". Here's an example in C: int x = 555; long long *l = (long long*)&x; x = 123; printf("%d\n", *l); This is a violation of the strict aliasing rule, which is undefined behavior. Unless it's compiled with no optimizations, or -fno-strict-aliasing which effectively disables this rule, the compiler is "free to do whatever it wants". Effectively though, it'll just print out 555 instead of 123. All undefined behavior is just stuff like this. The compiler output deviates from the expected input, and only maybe. You can imagine this kind of thing gets rather tricky with more aggressive optimizations, but this potential deviation is all that occurs. Race conditions, silent bugs, etc. can occur as the result of the compiler mangling your code thanks to UB, but so can crashes and a myriad of other things. It's also possible UB is completely harmless, or even beneficial. It's really hard to reason about that kind of thing though. Optimizing compilers can be really hard to predict across a huge codebase, especially if you aren't a compiler dev yourself. That unpredictability is why we say it's bad. If you're compiling code with something like TCC instead of clang, it's a completely different story. That's it. That's all there is to UB.
- publicdebates 11mo agoI think it's common to be taught that UB is very bad when you're new, partly to simplify your debugging experience, partly to help you understand and mentally demarcate the boundaries of what the language allows and doesn't allow, and partly because there are many Standards-Purists who genuinely avoid UB. But from my own experience, UB just means "consult your compiler to see what it does here because this question is beyond our pay grade." Interestingly enough, and only semi related, I had to use volatile for the first time ever in my latest project. Mainly because I was writing assembly that accessed memory directly, and I wanted to make sure the compiler didn't optimize away the variable. I think that's maybe the last C keyword on my bucket list.
- wrs 11mo ago> In Go, a slice is a fat pointer to a contiguous sequence in memory, but a slice can also grow, meaning that it subsumes the functionality of Rust’s Vec<T> type and Zig’s ArrayList. Well, not exactly. This is actually a great example of the Go philosophy of being "simple" while not being "easy". A Vec<T> has identity; the memory underlying a Go slice does not. When you call append(), a new slice is returned that may or may not share memory with the old slice. There's also no way to shrink the memory underlying a slice. So slices actually very much do not work like Vec<T>. It's a common newbie mistake to think they do work like that, and write "append(s, ...)" instead of "s = append(s, ...)". It might even randomly work a lot of the time. Go programmer attitude is "do what I said, and trust that I read the library docs before I said it". Rust programmer attitude is "check that I did what I said I would do, and that what I said aligns with how that library said it should be used". So (generalizing) Go won't implement a feature that makes mistakes harder, if it makes the language more complicated; Rust will make the language more complicated to eliminate more mistakes.
- auxiliarymoose 11mo agoWriting "append(s, ...)" instead of "s = append(s, ...)" results in a compiler error because it is an unused expression. I'm not sure how a newbie could make this mistake since that code doesn't compile.
- masklinn 11mo agoIndeed the usual error is b := append(a, …)
- weakfish 11mo agoHow is that an error if b is properly referenced? It’s perhaps a waste of memory but not wrong
- masklinn 11mo agoBecause `append` works in-place, Go slices are amortised, and the backing buffer is shared between `a` and `b`, so unless you never ever use a again it likely will have strange effects e.g. a := make([]int, 0, 5) a = append(a, 0, 0) b := append(a, 1) a = append(a, 0) fmt.Println(b) prints [0 0 0] because the following happens: a := make([]int, 0, 5) // a = [() _ _ _ _ _] // a has length 0 but the backing buffer has capacity 5, between the parens is the section of the buffer that's currently part of a, between brackets is the total buffer a = append(a, 0, 0) // a = [(0 0) _ _ _] // a now has length 2, with the first two locations of the backing buffer zeroed b := append(a, 1) // b = [(0 0 1) _ _] // b has length 3, because while it's a different slice it shares a backing buffer with a, thus while a does not see the 1 it is part of its backing buffer: // a = [(0 0) 1 _ _] a = append(a, 0) // append works off of the length, so now it expands `a` and writes at the new location in the backing buffer // a = [(0 0 0) _ _] // since b still shares a backing buffer... // b = [(0 0 0) _ _]
- kennykartman 11mo agoI find this a nice read, but I don't think it captures the essence of these PL. To me it seems mostly a well crafted post to reach a point that basically says what people think of these languages: "go is minimal, rust is complex, zig is a cool, hot compromise". The usual. It was fun to read, but I don't see anything new here, and I don't agree too much.
- Rikudou 11mo agoI think the Go part is missing a pretty important thing: the easiest concurrency model there is. Goroutines are one of the biggest reasons I even started with Go.
- auxiliarymoose 11mo agoAgreed. Rob Pike presented a good talk "Concurrency is not Parallelism" which explains the motivations behind Go's concurrency model: https://youtu.be/oV9rvDllKEg https://youtu.be/oV9rvDllKEg Between the lack of "colored functions" and the simplicity of communicating with channels, I keep surprising myself with how (relatively) quick and easy it is to develop concurrent systems with correct behavior in Go.
- PaulKeeble 11mo agoIts a bit messy to do parallelism with it but it still works and its a consistent pattern and their are libraries that add it for the processing of slices and such. It could be made easier IMO, they are trying to dissuade its use but its actually really common to want to process N things distributed across multiple CPUs nowadays.
- silisili 11mo agoTrue. But in my experience, the pattern of just using short lived goroutines via errgroup or a channel based semaphore, will typically get you full utilization across all cores assuming your limit is high enough. Perhaps less guaranteed in patterns that feed a fixed limited number of long running goroutines.
- theshrike79 11mo agoJust the fact that you can prototype with a direct solution and then just pretty much slap on concurrency by wrapping it in "go" and adding channels is amazing.
- macintux 11mo ago> the easiest concurrency model there is Erlang programmers might disagree with you there.
- 10000truths 11mo agoThe reason I really like Zig is because there's finally a language that makes it easy to gracefully handle memory exhaustion at the application level. No more praying that your program isn't unceremoniously killed just for asking for more memory - all allocations are assumed fallible and failures must be handled explicitly. Stack space is not treated like magic - the compiler can reason about its maximum size by examining the call graph, so you can pre-allocate stack space to ensure that stack overflows are guaranteed never to happen. This first-class representation of memory as a resource is a must for creating robust software in embedded environments, where it's vital to frontload all fallibility by allocating everything needed at start-up, and allow the application freedom to use whatever mechanism appropriate (backpressure, load shedding, etc) to handle excessive resource usage.
- kibwen 11mo ago> No more praying that your program isn't unceremoniously killed just for asking for more memory - all allocations are assumed fallible and failures must be handled explicitly. But for operating systems with overcommit, including Linux, you won't ever see the act of allocation fail, which is the whole point. All the language-level ceremony in the world won't save you.
- wavemode 11mo agoI imagine people who care about this sort of thing are happy to disable overcommit, and/or run Zig on embedded or specialized systems where it doesn't exist.
- vegabook 11mo agoThe last paragraph captures the essence that all the PL theory arguments do not. "Zig has a fun, subversive feel to it". It gives you a better tool than C to apply your amazing human skills, freely, whereas both Rust and Go are fundamentally sceptical about you.
- Klonoar 11mo agoI mean, if we're going to go there, you could take it a step further: Zig allows the programmer ego to run wild in a way that Rust and Go do not. This is perhaps somewhat natural; people like and want to be good at things. Where you fall on the trade off is up to you.
- bnolsen 10mo agoI might buy your argument except that without corporate sponsorship for zig several projects using a very young and unfinished zig exhibit world class performance and utility, apparently without herculean effort.
- saghm 11mo agoWhen it comes to our ability to write bug-free code, I feel like humans are not actually not that good at writing bug-free code. We just don't have any better way of producing software than that, and software is useful. This doesn't mean we're particularly good at it though, just that it's hard to motivate people to spend effort up front to avoid bugs when the cost of them is easy to ignore in the short term when they're not obvious. I feel like the mindset that languages that try to make them more apparent up front (which I honestly would not include Go as one of) are somehow getting in the way of us is pretty much exactly the opposite of what's needed, especially in the systems programming space (which also does not really include Go in my mind).
- xpe 11mo agoSelf-aware people are mindful about what "future them" might do in various scenarios, and they plan ahead to tamp down their worse tendencies. I don't keep a raspberry cheesecake in my fridge, even though that would maximize a certain kind of freedom (the ability to eat cheesecake whenever I want). I much prefer the freedom that comes with not being tempted, as it leads to better outcomes on things I really care about. In a sense, it is a powerful kind of freedom to choose a language that protects us from the statistically likely blunders. I prefer a higher-level kind of freedom -- one that provides peace of mind from various safety properties. This comment is philosophical -- interpret and apply it as you see fit -- it is not intended be interpreted as saying my personal failure modes are the same as yours. (e.g. Maybe you don't mind null pointer exceptions in the grand scheme of things.) Random anecdote: I still have a fond memory of a glorious realization in Haskell after a colleague told me "if you design your data types right, the program just falls into place".
- shevy-java 11mo agoUntil someone creates a new language that is better than these ...
- drnick1 11mo agoModern C++ is probably better than all of those if you need to interface with existing code and libraries, or need classic OOP.
- vibe_assassin 11mo agoI'd rather read 3 lines of clear code than one line of esoteric syntactic sugar. I think regardless of what blogs say, Go's adoption compared to that of Rust or Zig speaks for itself
- rishabhaiover 11mo ago> it is like C in that you can fit the whole language in your head. This is exactly why I find Go to be an excellent language. Most of the times, Go is the right tool. Rust doesn't feel like a tool. Ceremonial yet safe and performant.
- auxym 11mo ago> it is like C in that you can fit the whole language in your head. Sure, you can fit all of C in your head, including all the obscure footguns that can lead to UB: https://gist.github.com/Earnestly/7c903f481ff9d29a3dd1 https://gist.github.com/Earnestly/7c903f481ff9d29a3dd1 And other fun things like aliasing rules and type punning.
- legobmw99 11mo agoYeah, I think people find C appealing because it feels like you can fit the whole language in your head. I’ve yet to meet someone who has actually accomplished this in practice
- dismalaf 11mo agoOne of these is not like the others... Odin vs Rust vs Zig would be more apt, or Go vs Java vs OCaml or something...
- gf000 11mo agoYeah, at this point why not have a Scratch vs Rust vs Python article?
- forgotpwd16 11mo agoHave noticed Go/Rust/Zig are quite popular for self-contained natively-compiled network-oriented/system apps/utilities/services, and they're similar in their integrated compiler/package-management tooling. So for this use case that trio worths comparing.
- pm90 11mo agoI still don’t get the point of zig, at least not from this post? I really don’t want to do memory management manually. I actually think rust is pretty well designed, but allows you to write very complex code. go tries really hard to keep it simple but at the cost of resisting modern features.
- int_19h 11mo agoIf you don't want to do memory management manually, then you're not the intended target audience for Zig. It's a language where any piece of code that needs to do heap allocation has to receive an allocator as an explicit argument in order to be able to allocate anything at all.
- black_13 11mo ago[dead]
- deathanatos 11mo ago> I’m not the first person to pick on this particular Github comment, but it perfectly illustrates the conceptual density of Rust: But you only need about 5% of the concepts in that comment to be productive in Rust. I don't think I've ever needed to know about #[fundamental] in about 12 years or so of Rust… > In both Go and Rust, allocating an object on the heap is as easy as returning a pointer to a struct from a function. The allocation is implicit. In Zig, you allocate every byte yourself, explicitly. […] you have to call alloc() on a specific kind of allocator, > In Go and Rust and so many other languages, you tend to allocate little bits of memory at a time for each object in your object graph. Your program has thousands of little hidden malloc()s and free()s, and therefore thousands of different lifetimes. Rust can also do arena allocations, and there is an allocator concept in Rust, too. There's just a default allocator, too. And usually a heap allocation is explicit, such as with Box::new, but that of course might be wrapped behind some other type or function. (E.g., String, Vec both alloc, too.) > In Rust, creating a mutable global variable is so hard that there are long forum discussions on how to do it. The linked thread is specifically about creating a specific kind of mutable global, and has extra, special requirements unique to the thread. The stock "I need a global" for what I'd call a "default situation" can be as "simple" as, static FOO: Mutex<T> = Mutex::new(…); Since mutable globals are inherently memory unsafe, you need the mutex. (Obviously, there's usually an XY problem in such questions, too, when someone wants a global…) To the safety stuff, I'd add that Rust not only champions memory safety, but the type system is such that I can use it to add safety guarantees to the code I write. E.g., String can guarantee that it always represents a Unicode string, and it doesn't really need special support from the language to do that.
- Capricorn2481 11mo ago>> In Go and Rust and so many other languages, you tend to allocate little bits of memory at a time for each object in your object graph. Your program has thousands of little hidden malloc()s and free()s, and therefore thousands of different lifetimes. > Rust can also do arena allocations, and there is an allocator concept in Rust, too. There's just a default allocator, too. Thank you. I've seen this repeated so many times. Casey Muratori did a video on batch allocations that was extremely informative, but also stupidly gatekeepy [1]. I think a lot of people who want to see themselves as super devs have latched onto this point without even understanding it. They talk like RAII makes it impossible to batch anything. Last year the Zig Software Foundation wrote about Asahi Lina's comments around Rust and basically implied she was unknowingly introducing these hidden allocations, citing this exact Casey Muratori video. And it was weird. A bunch of people pointed out the inaccuracies in the post, including Lina [2]. That combined with Andrew saying Go is for people without taste (not that I like Go myself), I'm not digging Zig's vibe of dunking on other companies and languages to sell their own. [1] https://www.youtube.com/watch?v=xt1KNDmOYqA https://www.youtube.com/watch?v=xt1KNDmOYqA [2] https://lobste.rs/s/hxerht/raii_rust_linux_drama https://lobste.rs/s/hxerht/raii_rust_linux_drama
- teleforce 11mo ago>I’m not the first person to pick on this particular Github comment, but it perfectly illustrates the conceptual density of Rust: https://github.com/rust-lang/rust/issues/68015#issuecomment-835786438 https://github.com/rust-lang/rust/issues/68015#issuecomment-... Wow, Rust does take programming complexity to another level. Everything, including programming languages, need to be simple but no simpler. I'm of the opinion that most the computing and memory resources complexity should be handled and abstracted by the OS for example the address space isolation [1]. The author should try D language where it's the Goldilocks of complexity and meta programming compared to Go, Rust and Zig [2]. [1] Linux address space isolation revived after lowering performance hit (59 comments): https://news.ycombinator.com/item?id=44899488 https://news.ycombinator.com/item?id=44899488 [2] Ask HN: Why do you use Rust, when D is available? (255 comments): https://news.ycombinator.com/item?id=23494490 https://news.ycombinator.com/item?id=23494490 [2]
- gf000 11mo agoComplexity has to live somewhere. If it's not in the language, it's either in the runtime and/or your code and/or your code's undocumented behavior.
- tialaramex 11mo ago> In both Go and Rust, allocating an object on the heap is as easy as returning a pointer to a struct from a function. I can't figure out what the author is envisioning here for Rust. Maybe, they actually think if they make a pointer to some local variable and then return the pointer, that's somehow allocating heap? It isn't, that local variable was on the stack and so when you return it's gone, invalidating your pointer - but Rust is OK with the existence of invalid pointers, after all safe Rust can't dereference any pointers, and unsafe Rust declares the programmer has taken care to ensure any pointers being dereferenced are valid (which this pointer to a long dead variable is not) [If you run a new enough Rust I believe Clippy now warns that this is a bad idea, because it's not illegal to do this, but it's almost certainly not what you actually meant] Or maybe in their mind, Box<Goose> is "a pointer to a struct" and so somehow a function call Box::new(some_goose) is "implicit" allocation, whereas the function they called in Zig to allocate memory for a Goose was explicit ?
- saghm 11mo agoYeah, this is very confusing to me. I don't see how someone can conflate Go implicitly deciding whether to promote a pointer to the heap based on escape analysis without any way for the programmer to tell other than having to replicate the logic that's happening at runtime with needing to explicitly use one on the APIs that literally exist for the sole purpose of allocating on the heap without either fundamentally misunderstanding something or intentionally being misleading.
- throwaway2037 11mo ago> OOP has been out of favor for a while now I love these lines. Who writes this stuff? I'll tell you: The same people on HN who write "In Europe, X is true." (... when Europe is 50 countries!). > Zig is a language for data-oriented design. But not OOP, right? Or, OOP couldn't do the same thing? One thing that I have found over umpteen years of reading posts online: Americans just love superlatives. They love the grand, sweeping gesture. Read their newspapers; you see it every day. A smidge more minimalism would make their writing so much more convincing. I will take some downvotes for this ad hominem attack: Why does this guy have 387 connections on LinkedIn? That is clicking the "accept" button 387 times. Think about that.
- yxhuvud 11mo agoIt'd be very interesting to see an OO language that passes around allocators like zig does. There is definitely nothing in the concept itself that stops that.
- throwaway2037 11mo agoWhat about allocators in C++ STL (Standard Template Library)? Honestly, I have been reading & writing C++ for a squillion years, and (1) I have never used an allocator myself, and (2) never seen anyone else use it. (Granted, I have not seen a huge number of enterprise C++ code bases.)
- bnolsen 10mo agothey are very awkward to use in the current STL, they are part of the template definition. Back in the day EASTL did allocators much better but it never became a thing.
- riku_iki 10mo ago> (1) I have never used an allocator myself, and (2) never seen anyone else use it. arena allocators are necessity for high performance software, because heap allocations are magnitude slower.
- neonsunset 11mo ago[dead]
- qaq 11mo agowith LLMs started defaulting to go for most projects Rust for WASM Zig is what I'd use if I started a greenfield DBMS project
- badmonster 11mo ago[dead]
- dmix 11mo ago> If the number of questions online about “Go vs. Rust” or “Rust vs. Zig” is a reliable metric The human brain demands "vs" articles
- sheepscreek 11mo ago> I’m not the first person to pick on this particular Github comment, but it perfectly illustrates the conceptual density of Rust Eh, that's not typical Rust project code though. It is Rust code inside the std lib. std libs of most languages including Python are a masterclass in dark arts. Rust is no exception.
- gt0 11mo agoI think it overstates the complexity and difficulty of Rust. It has some hard concepts, but the toolchain/compiler is so good that it practically guides you through using them.
- frobisher 11mo agoAlthough I find my brainspace being dedicated to thinking about memory, rather than the problem at hand. Which can be a worthwhile cost if the benefits of speed and security are needed. But I think it's certainly a cognitive cost.
- notnullorvoid 11mo agoYou can use RC liberally to avoid thinking about memory though. The only memory problem to think about then is circular refs, which GC languages also don't fully avoid.
- thefox 11mo agoRust Alternatives https://blog.fox21.at/2025/03/09/rust-alternatives.html https://blog.fox21.at/2025/03/09/rust-alternatives.html
- forgotpwd16 11mo agofor author's specific criteria Thus not a general article. For some criteria Python will be a good Rust alternative. >Can I have a #programming language/compiler similar to #Rust, but with less syntactic complexity? That's a good question. But considering Zig is manually memory managed and Crystal/Go are garbage collected, you sidestep Rust's strongest selling point.
- archargelod 11mo agoThis list is missing Nim[1]: nice syntax, extremely fast, memory safe, small binaries [1] https://nim-lang.org https://nim-lang.org
- Ycros 11mo agoI'd recommend anyone looking at these three languages to give Odin a try.
- eliasdorneles 10mo agoI second that! I was trying Zig for some small projects, but ended up switching to Odin, because I found it much more comfortable!
- deleted 11mo ago[deleted]
- gzell 11mo agoAs we used to say, and what this discussion again reminds me of is: We don't need higher level languages, what we need is higher level programmers.
- ezst 11mo agoShould really consider adding scala-native to the comparison : https://scala-native.org/en/latest/ https://scala-native.org/en/latest/
- forgotpwd16 11mo agoThere're many languages that can be added in such comparison. Why Scala Native (which looks nice sure) over more prominent C/C++ successors/alternatives such as D, Nim, V, Odin, Hare, etc?
- ezst 11mo agoI think if fits well in this comparison, because Scala-native: - has the ergonomics, abstractions, expressiveness and conveniences of a high-level language with pointer-level semantics if/when needed (essentially covering the abstraction vs. cost spectrum of all those languages) - can be used with or without GC (same) - has the libraries and tooling to tackle massively concurrent/parallel workloads with ease (the niche that Go carved for itself) - offers the same memory safety guarantees as Rust, and possibly more in the future with capture-checking (a more general concept than borrow-checking to guarantee resources scoping at compile-time)
- jasfi 11mo agoNim hit the spot for a good low-level, fast language for me. The recommended GCs work well and it's easy to use.
- truth_seeker 11mo agoGo is a reasonable compromise, very hard to ignore.
- dannersy 11mo ago> This makes Rust hard, because you can’t just do the thing! I'm a bit of a Rust fanboy because of writing so much Go and Javascript in the past. I think I just got tired of all the footguns and oddities people constantly run into but conveniently brush off as intentional by the design of the language. Even after years of writing both, I would still get snagged on Go's sharp edges. I have seen so many bugs with Go, written by seniors, because doing the thing seemed easy in code only for it to have unexpected behavior. This is where even after years of enjoying Go, I have a bit of a bone to pick with it. Go was designed to be this way (where Javascript/Typescript is attempting to make up for old mistakes). I started to think to myself: Well, maybe this shouldn't be "easy" because what I am trying to do is actually complicated behind the scenes. I am not going to sit here and argue with people around language design or computer science. What I will say is that since I've been forced to be somewhat competent in Rust, I am a far better programmer because I have been forced to grasp concepts on a lower level than before. Some say this might not be necessary or I should have known these things before learning Rust, and I would agree, but it does change the way you write and design your programs. Rust is just as ugly and has snags that are frustrating like any other language, yes, but it was the first that forced me to really think about what it is I am trying to do when writing something that the compiler claims is a no-no. This is why I like Zig as well and the syntax alone makes me feel like there is space for both.
- BenGosub 11mo agoReading about the the complexity of Rust makes me appreciate more OCaml. OCaml also has a Hindley Milner type system and provides similar runtime guarantees, but it is simpler to write and it has a very, very fast compiler. Also, the generated code is reasonably fast.
- ayubu 10mo ago…and the compiler is very fast. I’d say that OCaml is now a mature language with modest but steady growth in the standard library, while still introducing ambitious new features in the compiler—such as the effect system.
- grougnax 11mo agoIt's obvious that Rust is the best.
- msie 11mo agoSo easy to get stuck doing nothing but contemplate what language you should use for your next project.
- Havoc 11mo agoAside from right tool I’d add two more criteria. 1) Complementary tools. I picked python and rust for obvious reasons given their differences 2) Longevity. Rust in kernel was important to me because it signaled this isn’t going anywhere. Same for rust invading the tool stacks of various other languages and the rewrite everything in rust. I know it irritates people but for me it’s a positive signal on it being worth investing time into
- scotty79 11mo agoI've been using Zig for few days. And my gotchas so far: - Can't `for (-1..1) {`. Must use `while` instead. - if you allocated something inside of a block and you want it to keep existing outside of a block `defer` won't help you to deallocate it. I didn't find a way to defer something till the end of the function. - adding variable containing -1 to usize variable is cumbersome. You are better of running everything with isize and converting to usize as last operation wherever you need it. - language evolved a bunch and LLMs are of very little help.
- scotty79 11mo agoI don't know if that's just aged noob in me speaking but so far, while Rust has "zero cost abstractions", Zig feels like it has "Zero abstractions". Deallocating the wrong thing or the right thing too soon bit me in th ass so much already that I feel craving for destructors.
- riku_iki 10mo agoRust is not zero cost abstractions, they make decision on case-by-case basis.
- scotty79 10mo agoIt's their tagline and it's how it feels. I cen freely abstract. Zig is kind of making me index into byte array all the time.
- riku_iki 10mo agoRust may feel like this in general, but I seen multiple discussions when people spot cases where rust is much slower than C++, they start looking at them, and the finding is that Rust is not zero-cost abstraction, and induce penalty sometime, while C++ is always zero cost abstraction.
- rohankhameshra 11mo agoLove Go and Rust depending on usecase, but yet to check Zig
- jpfromlondon 11mo agoRust lets you be a bad programmer and that is unforgivable, using Zig will make you a better person.
- dana321 11mo agolazy_static with either a mutex or a RwLock. I actually love how rust gatekeeps the idiots from programming it, probably why Linus Torvalds allowed rust into the kernel, but not C++.
- srameshc 11mo agoI started using Rust out of a need , it's tough and I thought I can learn any language easily. But I think from my short experience , Rust teaches how to be a good and thoughtful programmer. My reason to continue learning Rust.
- intalentive 11mo ago>You have more control here than you have even in C: To allocate bytes, you have to call alloc() on a specific kind of allocator You can write your own allocator in C. You don't have to use malloc.
- bnolsen 10mo agoyou could fully redesign libc to be modern and toss out the null terminated string concept and use fat pointers and slices. But at that point why not consider moving onto a more modern language with things like explicit type conversions, modern PEG type grammar, etc.
- bird0861 11mo agoI've been asking around the last week about Go vs Elixir vs Zig, I'd love to get feedback here too. I only have time for one and I'm looking for something that can replace a lot of the stuff I do with Python. I don't have time to wait for Mojo.
- lucyjojo 11mo agoi don't see the point of these discussions. nobody will convince anybody of anything in this thread. use the stuff you want people.
- oconnor663 11mo ago> What is the dreaded UB? I think the best way to understand it is to remember that, for any running program, there are FATES WORSE THAN DEATH. I love this. I'm gonna steal this :) > I’m not the first person to pick on this particular Github comment, but it perfectly illustrates the conceptual density of Rust: The overall point here is fair, but I think it's important to clarify that (iiuc) this comment is talking about a "soundness hole". Soundness holes are cases where there's a bug in the compiler or in a library that allows someone to commit UB without writing `unsafe`. Given the goals of Rust, it doesn't matter how ungodly complicated and contrived the example is. If it produces UB without `unsafe`, then it's a bug that needs to be fixed. In practice, that means a lot of issue threads about soundness involve mind-numbing code samples that mash different features together in unintuitive ways. But that's a good thing! No one's saying you'll ever need to look at code like this in the wild. They're saying that no matter how hard you (or your coworkers or your dependencies) try, Rust should never fail to protect memory safety in safe code.