8 ms·
Rust is not "more" safe than a GC language because it has a borrow checker.
by Thaxll 7y ago
Rust is not "more" safe than a GC language because it has a borrow checker.
- weberc2 7y agoIt’s more safe than those languages because of its type system. Memory safety isn’t the only kind of safety, after all. :) NOTE: maybe the parent edited his comment between my reply and yours?
- blub 7y agoI see this statement is oft repeated on HN, but no proof is offered in its support. Rust can guarantee the elimination of race conditions in low-level multi-threaded code, but aside from that there's nothing really safer about its type system compared to say Java. And one would anyways use a higher-level concurrency library in Java, or perhaps the concurrency annotations, making the formerly mentioned advantage barely relevant. Memory safety is certainly not the only kind of safety, but it is alas the only kind of safety supported by Rust (and every other language except C and C++).
- staticassertion 7y ago> Memory safety is certainly not the only kind of safety, but it is alas the only kind of safety supported by Rust (and every other language except C and C++). I think the parent poster's entire point was that Rust does provide safety beyond memory safety. Perhaps not as a forced concept, ie: you do not have to express all structures as finite state machines, but you can very elegantly express your structures as finite state machines. And you can do so in a way that most other languages can't, because of affine types.
- blub 7y agoOk. Where's the proof that finite state machines are safer? Or that expressing structures in a certain way is safer?
- staticassertion 7y agoA type system that encodes FSTs makes it impossible to express invalid state transitions, hence the safety. Anyway, I'm only clarifying that the parent poster was explicitly talking about safety outside of memory safety.
- blub 7y agoI don't see why such a minor thing is considered an important safety improvement. Using optionals, result types and match would give me a nice feeling too, but I won't claim that my code's safer because of that. Those are super low-level tools.
- staticassertion 7y agoI didn't attempt to qualify "importance" of the method, only give one example where Rust provides a safety mechanism that other languages do not; the ability to encode finite state machines into the type system with no risk of reusing invalid states. Whether you care about that or think it's valuable does not change that it is a way of encoding a model into your type system to make a class of errors impossible.
- blub 7y agoQuantifying the impact of the method is very relevant though, because if using FSMs makes code 0,001% safer, your statements that this makes a class of errors impossible or that Rust provides additional safety mechanisms are both true, and yet should have no bearing on the real-world safety of a program written in Rust. And the lack of evidence in this area suggests to me that the safety benefit is indeed negligible.
- weberc2 7y ago> And the lack of evidence in this area suggests to me that the safety benefit is indeed negligible. It should only suggest to you that it is prohibitively expensive to control for all of the different variables in order to provide a remotely reliable quantification.
- weberc2 7y agoRust's type system supports any type of resource, not just memory. The same isn't true for garbage collectors (and no, "finalizers" is not correct resource management). Also, real enum types (including optional) and pattern matching. I'm sure you can come close with Java using interfaces or something, but it's going to be cludgy and tedious in practice (especially if you have primitive variants). To be clear, I'm only stating that Rust is safer, not that safety is the end-all-be-all for every single application and you should never use COBOL or Java or even that you should prefer Rust over them in the general case or anything of the sort.
- blub 7y agoAnd I'm stating that I don't see why it's safer than Java, even if Java doesn't have pattern matching (it does have optional). It is nice to be able to encode something in the type system, but one could just as well use design by contract or unit testing, and these actually do have supporting evidence in their favor. Is there even any supporting evidence that static typing results in better quality? I think most would agree that it improves performance, makes refactoring and managing the code base easier. Note: I'm also a fan of static type systems and of encoding relationships and requirements in them, but I have no proof that this actually improves quality. It makes things easier to reason about for me and maybe it eliminates some classes of errors, however it's not obvious that these classes of errors represent a noticeable amount of the total.
- vardump 7y agoIn Java, you can modify same data from multiple threads without the compiler complaining anything. In Rust that would cause a compile time error, until you synchronize the data.
- cesarb 7y agoNot only multiple threads, a common mistake is to modify a collection while iterating it, which can happen within a single thread (and it's even worse when it happens conditionally, so it'll only fail sometimes). The thing I love the most in Rust is the duality between "&mut" and "&": when you have a "&mut" reference to something, you know nobody else has any "&mut" or a "&" reference to it, so you can modify the data structure without worry; and when you have a "&" reference to something, you know nobody else has any "&mut" reference to it, so you can read the data structure without worry. I wish I had something like that in Java, instead of having to sprinkle "synchronized" everywhere just in case (which not only doesn't protect against a recursive call within the same thread, but also can lead to AB/BA deadlocks... which is made so much more fun by code called from executors which have a ThreadPoolExecutor.CallerRunsPolicy, meaning not only will it happen only in production, it will only happen in production when the system is overloaded. Took us weeks of debugging to reproduce one instance of that...).
- atoav 7y agoI program Python, Rust and C and I can assure you that my Rust programs certainly have the least amount of bugs. Not because Rust is a "safe" language, but because certain types of silly mistakes I tend to make in Python and C just wouldn't compile. Aside from the language, understanding the Rust way of things certainly improved my code in Python and C too. And with "the Rust way" I mean the way you need to structure things if you don't want to end up fighting the borrow checker all the time. The concepts they use there make a lot of sense even in languages that don't enforce them and have been known before Rust was ever invented. Edit: so in essence subjectively it makes me find more mistakes easier, it provides a beautiful environment for test driven development and working with it is a pleasure if you understood how things are meant to be done. This is all no real proof, but I certainly would feel more secure implementing critical code in Rust than I would doing the same thing in Python or C.
- Const-me 7y ago> because certain types of silly mistakes I tend to make in Python and C just wouldn't compile. Python and C are similar in that regard. You can compile almost anything in them. Will then crash in runtime if not OK, gracefully for Python, the whole process for C. Languages like Java or C# are different. Both are strongly typed, a lot of things are checked by compilers. I believe C# is safer than Rust because native code surface is much smaller. Safe Rust is fundamentally limited by that borrow checker. Read the source of Rust standard library, you'll see tons of unsafe code everywhere. Rust developers probably did a good job verifying their implementations of stuff like Vec and HashMap, but there're less used parts of the standard library. Non-standard third-party libraries also using unsafe. .NET doesn't need any unsafe code for such things. Even fundamental parts of the standard library, like List and Dictionary, are 100% managed code, to be specific it's C#: https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/Collections/Generic/List.cs https://github.com/dotnet/coreclr/blob/master/src/System.Pri... Same is true for majority of third-party libraries: unsafe is supported by the languages, but using it may complicate deployment.
- steveklabnik 7y agoThe standard library has far more unsafe code than an average Rust project. One of the major reasons why is “needs a lot of unsafe to implement” is a historical criteria for “this belongs in the standard library”.
- bglusman 7y agoTo be fair, GC only collects memory and Rust's ownership manages ownership of other resources like files and ports and stuff too as I understand it!
- twic 7y agoMore generally, it lets you tie resources to syntactic scopes. An example in the standard library is MutexGuard - you get one when you lock a mutex, and when you drop it, that releases the mutex. You can't forget to release the mutex, and you also can't release it too early, because then you lose access to the data protected by the mutex. There are ways to defeat this, of course, but you have to go out of your way to do it. I've used a library which uses a similar pattern for writing to a ring-buffered message queue: when you grab a slot in the queue to write to, you get a SlotGuard, and when you drop it, you lose access to the slot, but that commits the slot and lets other threads read it.
- liara_k 7y agoNo, but Rust provides this memory safety without GC, which is AFAIK, unique in a mainstream language. The type system knowing about ownership and borrowing also allows the elimination of race conditions (outside of `unsafe`, of course...). I don't know of a GC language that also does that, though obviously that doesn't mean there isn't one... ;)
- echelon 7y ago> elimination of race conditions Rust doesn't get rid of race conditions. It lets you write memory safe concurrent code. These are two separate things. You still have to be cognizant that code may not run in the order you expect. This is still a great language feature.
- xfer 7y agoData races shouldn't be happening with a GC'd language with a proper memory model, getting this right is important. Haskell has no dataraces if you don't use IORefs in safe code. Afaik java has a happens-before memory model that can be used to detect races.
- legulere 7y agoRust is more multi-threading safe than GC languages because of the borrow checker: https://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.html https://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.h...
- dom96 7y agoI don't think this is a fact for _all_ GC'd languages. For example, Nim is a GC'd language and it's also multi-threading safe. It perhaps doesn't give as much freedom as Rust, but it does still achieve safety. The compiler restricts sharing of memory because each thread gets its own GC, and for locks the compiler verifies that variables are locked [1]. 1 - https://nim-lang.org/docs/manual_experimental.html#guards-and-locks-guards-and-the-locks-section https://nim-lang.org/docs/manual_experimental.html#guards-an...