7 ms·
> I was looking for a replacement for C, but Rust is actually a replacement for C++. Totally different beast - powerful but complex. I've seen this sentiment a
by pcwalton 2y ago
> I was looking for a replacement for C, but Rust is actually a replacement for C++. Totally different beast - powerful but complex.
I've seen this sentiment a lot, and I have to say it's always puzzled me. The difference between Rust and basically any other popular language is that the former has memory safety without GC†. The difference between C++ and C is that the former is a large multi-paradigm language, while the latter is a minimalist language. These are completely different axes.
There is no corresponding popular replacement for C that's more minimalist than Rust and memory safe.
† Reference counting is a form of garbage collection.
- zamalek 2y ago> † Reference counting is a form of garbage collection. I agree with Raymond Chen's take on the academic definition of GCs[1], and therefore Rust is certainly a GC'd language (because your code behaves as though memory is infinite... usually). It's probably one of the first examples of "static garbage collection" - though I'm sure someone will point out a prior example. [1]: https://devblogs.microsoft.com/oldnewthing/20100809-00/?p=13203 https://devblogs.microsoft.com/oldnewthing/20100809-00/?p=13...
- jonahx 2y agoThis feels like deliberate misdirection, because in most practical cases what people mean is "some memory management process that will slow my program down non-trivially". By this definition Rust does not have GC whereas Go, eg, does. The "simulates infinite RAM" is an interesting perspective but simply not the subject of most conversations.
- zozbot234 2y agoManual heap allocation can slow the program down non-trivially compared to using an arena which is cleaned up all at once; hence, manual heap allocation is a kind of GC. Checkmate atheists.
- caspper69 2y agoI went down a path researching the viability of region based memory management (a form of arenas). A language based on such a paradigm can be provably memory safe, and regions can have their own allocators and optionally provide locking when the regions are shared. This approach obviates the need for reference counting individual allocations (since regions are tracked as a whole), but it suffers from excess memory usage in the event of many short-lived allocations (i.e. they leak until the entire region's allocations go out of scope). But those types of memory accesses can be problematic in every systems language as they can eventually cause memory fragmentation. That problem can be minimized using per-allocation reference counting, but that can incur a heavy performance hit. Although not having to use it everywhere could minimize the impact. The plus side is you don't have to worry about borrow checking, so such a language can be more flexible than Rust, while still maintaining the memory safety aspect. The question, as always, is: is the juice worth the squeeze? Truthfully, I suspect no. The Rust train has left the station and has a decade head start. Even if it is a pain in the ass, lol.
- zozbot234 2y agoYou may be interested in Rust language proposals for local memory allocators and "storages"; they may be enough for something very much like this. The lifetime concept in Rust is quite close already to that of a "region", i.e. an area of memory that the lifetime can pertain to.
- caspper69 2y agoDepending on the semantics of the implementation, something like that would go a long way toward eliminating one of my biggest issues with Rust. For a low-level systems language, it is imperative to offer 2 things, which are currently a pain in Rust: (1) you must be able to "materialize" a struct at an arbitrary location; why? Because hardware tables exist at a specified location and are provided by hardware- they are not created or instantiated in the host language; and (2) be able to reference structs from other structs, which immediately triggers lifetime annotations, which begin to color everything they touch, must like async does to functions. And I admit, I loathe the borrow checker. Ironically, I never really have problems with it, because I do understand it, it's just that I find it too limiting. Not everything I want to do is unsafe, and I hate the way it has made people think that if you really do know better than the borrow checker, you must clearly be doing something wrong and you should re-architect your code. It's insulting.
- nemetroid 2y agoBy that definition, a C++ program with heavy usage of std::shared_ptr has GC.
- cmrdporcupine 2y agoAnd it does. Reference counting is garbage collection. And std::shared_ptr, or Rust's Rc/Arc are basically lightweight GC runtimes inside your program.
- coldtea 2y agoIsn't that the point?
- nemetroid 2y agoI don't think it's the point of the comment I replied to, no.
- imtringued 2y agoBy this logic you're writing the garbage collector by hand in C.
- hansvm 2y agoIt's not a perfect analogy, but if you want to put yourself in the shoes of the people making it: 1. Rust is an immensely complicated language, and it's not very composable (see the async debacle and whatnot). On the simple<->complex slider, it's smack dab on the right of the scale. 2. Ignoring any nitpicking [0], Zig is memory-safe enough in practice, placing it much closer to Rust than to C/C++ on the memory safety axis. My teammates have been using Zig for nearly a year, and the only memory safety bug was (a) caught before prod and (b) not something Rust's features would have prevented [1]. The `defer` and `errdefer` statements are excellent, and much like how you closely audit the use of `unsafe` in Rust there is only a small subset of Zig where you actually need to pull your magnifying glass out to figure out if the code has any major issues. In terms of memory issues I've cared about (not all conforming to Rust's narrow definition of memory safety), I've personally seen many more problems in Rust projects I contribute toward (only the one in Zig, plus a misunderstanding of async as I was learning the language a few years ago, many of varying severity in Rust, at this point probably more code written in Zig than Rust, 10yoe before starting with either). With that in mind, you have C/C++ on the unsafe axis and Zig/Rust on the safe axis. The complexity axis is self-explanatory, fleshing out the analogy. Is Zig memory-safe? No, absolutely not. Does that mean that Rust will win out for some domains? Absolutely. In practical terms though, your average senior developer will have many memory safety bugs in C/C++ and few in Zig/Rust. It's a reasonable way to compare and contrast languages. Is it a perfect description? No, the map is not the territory. It's an analogy that helps a lot of people understand the world around them though. [0] Even Python is simpler than Rust, and it's memory-safe. If we're limiting ourselves to systems languages, you still have a number of options like Ada and Coq. Rust is popular because it offers a certain tradeoff in the safety/performance/devex Pareto curve, and because it's had a lot of marketing. It's unique in that niche, by definition, but it's far from the only language to offer the features you explicitly stated. [1] It was just an object pool, and the (aggregate) resetting logic wasn't solid. The objects would have passed through the borrow checker with flying colors though. Edit: To your GC point, many parts of Rust look closer to GC than not under the hood. You don't have a GC pause, but you have object pools (sometimes falling back to kernel object pools) and a variety of allocation data structures. If RC is a GC tactic, the extra pointer increment/decrement is negligible compared to what Rust actually does to handle its objects (RC is everything Rust does, plus a counter). That's one of my primary performance complaints with the language, that interacting with a churn of small objects is both expensive and the easiest way to code. I can't trust code I see in the wild to behave reasonably by default.
- tialaramex 2y agoToday all of the code I'm not paid to write is in Rust. I spent many happy years previously getting paid to write C (I have also been paid to write Java, PHP, Go and C#, and I have written probably a dozen more languages for one reason or another over the years but never as specifically a thing people were paying me to do) I always thought C++ was a terrible idea, from way before C++ 98, I own Stroustrup's terrible book about his language, which I picked up at the same time as the revised K&R and it did nothing to change that belief, nor have subsequent standards. However, I do have some sympathy for this sentiment about Rust being a better C++. Even though Rust and C++ have an entirely different approach to many important problems the syntax often looks similar and I think Zig manages to be less intimidating than Rust for that reason if you don't want that complexity. Personally I had no interest in C++† and I have no serious interest in Zig. † Ironically I ended up caring a lot more about C++ after I learned Rust, and most specifically when understanding how Rust's HashMap type works, but I didn't end up liking C++ I just ended up much better informed about it.
- munificent 2y agoBoard games and craft beers are utterly unrelated objects who have commonality on essentially no axes (except sitting on tables, I guess). And, yet, if you like one, there's a very good chance you like the other. I think that's where the sentiment comes from. It's not that Rust is similar to C++ in terms of the actual languages and their features. It's that people who like C++ are morely likely to like Rust than people who like C are. I would argue that C is not a minimalistic language either. There is a lot under the hood in C. But it feels small in a way that Rust and C++ don't. I think Rust and C++ appeal to programmers who are OK with a large investment in wrapping their head around a big complex language with the expectation that they will be able to amortize that investment by being very productive in large projects over a large period of time. Maybe sometimes the language feels like trying to keep a piece of heavy duty machinery from killing you, but they're willing to wrestle with it for the power you get in return. The people who are excited about Zig and C wants something that feels more like a hand tool that doesn't demand a lot of their attention and lets them focus on writing their code, even if the writing process is a little more manual labor in return.
- estebank 2y ago> Maybe sometimes the language feels like trying to keep a piece of heavy duty machinery from killing you, but they're willing to wrestle with it for the power you get in return. It's funny because to me there's an analogy with heavy machinery but materially different: there are some industrial machines that have two buttons that need to be actuated to activate the mechanism, separated by arm length in order to ensure that the operator's arms are out of the way when the limb crunching bits are moving. I see Rust that way, engineering the safe way to do things as the path of least resistance, at the cost of some convenience when trying to do something "unsafe".
- incrudible 2y agoOkay, but now imagine a kitchen appliance that did the same thing. It would not be a big seller. Of course a kitchen appliance can injure and even kill you, but it probably wouldn’t unless you try really hard. Most of programming is like that, but in the few cases where there literally are lives at stake, memory safety by itself will not do much for you and performance is going to be a secondary concern. Zig does have safety features that C/C++ do not have, but also one should not underestimate the security implications of language complexity by itself.
- gens 2y agoIt is not about memory safety or anything like that. It is about simplicity. If you say "you can't do x with y in C++" you will get an "yes you can, you just use asd::dsadasd::asdadqwreqsdwerig_hfdoigbhiohrf() with weaorgoiawr flag". From what I have seen from Rust, it is similar. I don't want to fill my brain with vim bindings.. cough.. Rust ways of doing something. I just want to code my hobby game engine v7. That said, I am happy to use software written in it. Even though the evangelists can be really annoying.
- coldtea 2y agoThe similarity between C++ and Rust is that both bust your balls with complexity for programming at large. And the inverse goes for C and Zig. Those are the axes relevant to the parent in the context of their comment - not specific language semantics or core features.
- defen 2y ago> There is no corresponding popular replacement for C that's more minimalist than Rust and memory safe. In the real world, memory safety is not all-or-nothing (unless you're willing to concede that Rust is not safe either, since unsafe Rust exists). I'm working on an embedded project in Rust and I'd MUCH rather be using Zig. The only safety thing that Rust would give me that Zig does not is protection from returning pointers to stack-allocated objects (there are no dynamic allocations and no concurrency outside of extremely simple ISRs that push events onto a statically allocated queue). But in exchange I have to deal with the presence of unsafe Rust, which feels like a gigantic minefield even compared to C.
- zozbot234 2y ago> But in exchange I have to deal with the presence of unsafe Rust, which feels like a gigantic minefield even compared to C. I think idiomatic coding norms for unsafe Rust are still a bit half-baked, and this is where something like Zig can have an advantage of sorts. You can see this also, e.g. in the ongoing proposals for a Pin<> alternative.
- throwawaymaths 2y agoprotection from returning stack pointers seems to be detectable with static analysis of zig AIR. https://github.com/ityonemo/clr https://github.com/ityonemo/clr
- sesm 2y ago> There is no corresponding popular replacement for C that's more minimalist than Rust and memory safe. There is Objective-C, it fits your definition of memory safety.
- pcwalton 2y agoObjective-C and Swift are the reason why I added the footnote. (Also Objective-C is very, very much not memory safe.)
- vitiral 2y agoFrom what I understand that language is Zig, no? Also, there's FORTH!
- wtetzner 2y agoI don't think Zig is memory safe?
- vitiral 2y agoI was replying to this bit > difference between C++ and C is that the former is a large multi-paradigm language, while the latter is a minimalist language. These are completely different axes. > There is no corresponding popular replacement for C that's more minimalist than Rust and memory safe. Edit: oh, I never read the last bit "and memory safe" -- well ya, that's kind of rust's major advantage.
- baranul 2y agoZig is not memory safe. It's one of those "can be more safe than C" modern alternative languages. This includes those various C/C++ alternatives that use a GC or optional one (that users can disable), to provide or increase memory safety. Some of the confusion and drama surrounding Zig, appears to be the vain attempt of marketing it as "safer" than "unsafe Rust". The questionable marketing tactic has sparked numerous arguments and debates.
- bmacho 2y ago> > I was looking for a replacement for C, but Rust is actually a replacement for C++. Totally different beast - powerful but complex. > The difference between Rust and basically any other popular language is that the former has memory safety without GC†. The difference between C++ and C is that the former is a large multi-paradigm language, while the latter is a minimalist language. These are completely different axes. Indeed. Let one axis be the simple/multi paradigm. Let the other axis be no memory management / automatic memory management without GC / GC. This divides the plane into 6. In the simple + no memory management sits C and Zig, and in the multiparadigm + memory safe without GC segment sits C++ and Rust. > There is no corresponding popular replacement for C that's more minimalist than Rust and memory safe. Those are some weird requirements for "being a replacement", but it is obviously true, as you picked them such.