3 ms·
The fact they've managed to bring safety to the masses without a GC is arguably the #1 reason for Rust's success. This has been a good move.
by qalmakka 3y ago
The fact they've managed to bring safety to the masses without a GC is arguably the #1 reason for Rust's success. This has been a good move.
- gwbas1c 3y ago> The fact they've managed to bring safety to the masses without a GC is arguably the #1 reason for Rust's success. This has been a good move. That's an understatement. Rust doesn't require a framework / runtime. Unlike NodeJS, Python, Java, C#, ect; when you ship a Rust program, it has no external requirements. More important: Because Rust can create libraries that adhere to the C calling convention, you can create libraries that you can call from NodeJS, Python, Java, C#, ect. The fact that those systems have a heavyweight runtime (with GC) makes it very hard to create a library in one environment and call it from the other. I do think there's room for an "R2" that is semantically identical, but designed to be easier to understand. Probably the biggest room for improvement is using generics for things like RC, ARC, Mutex. I'd rather use something like keywords; and leave generics for user-defined types. This way, when trying to understand what something "is," the "how the memory is tracked" is semantically different from "what the struct is." (Even though under the hood they are the same thing.)
- thinkharderdev 3y ago> using generics for things like RC, ARC There is an unstable feature for "box syntax" which both allows you to construct a `Box<T>` as let foo = box a (instead of let foo = Box::new(a)) but also to use box as a keyword in pattern matches to deref the box automatically. So struct Foo { value: Box<Bar> }; let Foo { value: box Bar } (in which case value is bound to a &Bar) which was really nice. It got subsumed into a more generic "deref patterns" project which doesn't seem to be going anywhere but I hope it does because it makes the language much more ergonomic IMO.
- SkiFire13 3y agoThe `box` syntax to create `Box`es has been removed because it was broken. The initial idea was to have it initialize the value directly in the heap, but that never worked for function calls. The `box` pattern instead remained as it was still useful to have (really unfortunate for the perma-unstable status though).
- thinkharderdev 3y agoAh didn't realized it had been removed. I gave up on it after it became clear it was never going to make it into stable rust. I do hope deref patterns gets some traction though as it could really be a nice feature.
- TylerE 3y agoI push back, strongly, on the notion that Rust in it's current state is "for the masses".
- qalmakka 3y agoI haven't said that. I've said they've brought safety to the masses.
- dgb23 3y agoThis claim is a bit too broad based on my limited understanding. Please correct me if I'm wrong: First, Rust is not actually a memory safe language. It makes writing memory safe code easy and nudges you towards writing "unsafe" code in specific places. This is a good thing and many get away with not requiring programmer asserted safety. But it's also important to note that ultimately it relies on it. Second, The borrow checker seems to primarily check that you're doing RAII properly. In a sense it answers the question of: "What if we get the predictable nature of stack allocated memory for the heap?" Clever, but that leads to a proliferation of lifetime annotations (which are part of your types) and makes code very brittle and rigid if spelled out as is. Because every lifetime that is encoded that way, has to fully cover the scope that encloses all of its usage. And if that weren't enough, it also infects almost every data structure that is some way composed of references. There seems to be multiple ways of dealing with this issue that I've come across when learning the language: 1. Avoiding pointer references whenever possible and using self-managed vector/slice/hashmap references. 2. Introducing GC via reference counting. 3. Cloning. 4. Macro or trait abstraction. When we're doing 1, we don't gain much utility from the borrow checker. When doing 2/3 we would be better served if we used a language with a battle hardened and optimized GC runtime. I've seen 4 in some cases, but never looked like it's "bringing safety to the masses". The whole API around traits and macros is very rich, very sophisticated and very subtle. I would rather phrase it as: "Rust brings ML/functional concepts to C++ programmers and it explores a new space of compiler optimizations based on that." However the Rust _community_ does bring these concepts to the masses. They have written excellent books and recorded multi hour long videos explaining and exploring the language and making this all accessible.
- steveklabnik 3y agoBy the standard of your “first,” no language is a memory safe language. They all must rely on unsafety in the implementation of their runtimes in the same sense that Rust builds safe abstractions on top of unsafe code, and many even offer FFI, which is conceptually similar to calling an unsafe function.
- titzer 3y agoMost memory safe languages lack enough power to implement their own runtime systems (except in an extremely inefficient way), because so many languages ultimately rely on an implementation in another unsafe language that has access to machine capabilities. Implementing the runtime system in the language itself is a black art that requires an unsafe dialect or extension. E.g. all the Java-in-Java VMs sneak dialect features in through intrinsic classes like "Pointer" and such that are recognized by their own extended compilers.