4 ms·
> It only means that the data model doesn't agree with Rust's rules for modeling data (which exist to ensure memory safety in the absence of a GC). This doesn’
by forrestthewoods 5y ago
> It only means that the data model doesn't agree with Rust's rules for modeling data (which exist to ensure memory safety in the absence of a GC).
This doesn’t seem correct at all?
GC merely solves freeing memory when it is no longer needed. But it does not solve parallel access.
One of the beauties of Rust is that you can write highly parallel code and if it compiles it works. Meanwhile Python languishes behind the GIL. GC does not even attempt to solve multithreaded memory access.
I’m happy to be corrected if I’m wrong or missing something here.
- verdagon 5y agoThat's a fair point. I'd add: some GC'd languages solve this with sending around deeply immutable objects (functional languages mostly), in a way that can be more flexible than the way Rust handles immutable objects.
- throwaway894345 5y agoYou're right on the local point that Rust's ownership rules guarantee correctness in the case of parallel access while GCs do not; however, the broader point is that Rust's ownership rules also reject many programs which would be correct with GC. For example: fn foo<'a>() -> &'a [u8] { let v = vec![0, 1, 2]; // returns a value referencing data owned by the current function v.as_slice() } vs Go's: func foo() []uint8 { // subject to escape analysis, but code like this would likely return // a fat pointer into the heap--no complaints because there's a GC. return []uint8{0, 1, 2} } > One of the beauties of Rust is that you can write highly parallel code and if it compiles it works. Meanwhile Python languishes behind the GIL. GC does not even attempt to solve multithreaded memory access. Python's GIL is unrelated to GC, but yes, Rust's borrow checker guarantees correct parallel access of memory. But I think this benefit is overblown for a couple reasons: 1. contrary to popular opinion, if you've learned how to write parallel programs, it's not tremendously difficult to write them correctly without a borrow checker. In my experience, whatever time I've saved debugging pernicious data races is lost by the upfront cost of pacifying the borrow checker. Maybe this wouldn't hold for people who aren't experienced with writing parallel code (but I imagine such people would have a harder time grokking the borrow checker as well). 2. most data races in my experience aren't single threads on a host accessing a piece of shared memory, but rather many threads on many hosts accessing some network resource (e.g., an S3 object). The borrow checker doesn't help here at all, but you still have to "pay the borrow checker tax". Again, this isn't a tirade against the borrow checker, but an insistence that tradeoffs exist and it's not just a "you're just doing it wrong" sort of thing.
- richardwhiuk 5y agoThe equivalent to the go is returning the Vec.
- throwaway894345 5y agoMy example is probably not very good. Let’s say you have a function which implements a callback. The function takes a &str and returns some subslice. Let’s say you want to implement another function which implements that same interface, but returns the string lowercases. In Rust, you have to update the interface, you have to update all implementations, and you have to jump through hoops to avoid unnecessary cloning in the subslice case. In Go or other GC languages, there aren’t “owned” vs “unowned” types, so you don’t have to make any updates to the interface or other implementations. In a sense, GC allows us to abstract over ownership.
- layoutIfNeeded 5y ago>Rust's ownership rules guarantee correctness in the case of parallel access while GCs do not That’s a dangerous misconception. The Rust ownership model only guarantees that the program is free of data races. That’s a necessary but not sufficient condition of program correctness.
- forrestthewoods 5y agoEhhh I’d have to hard disagree with #1. But we’ll likely just have to agree to disagree. Maybe I’m just a bad enough programmer I write parallel bugs. But C++ certainly doesn’t make it easy to write correct code in any way. I personally think it’s pretty darn difficult to ensure correctness in a large program. Especially when multiple programmers are involved. And especially when you are adding features to an existing system. However I will also admit that I haven’t written a large Rust program so I can’t claim to have run into all of its warts. There’s no silver bullets in life. I work primarily in video games. GC is the bane of existence and is something that provides seriously negative value. We definitely agree it’s all a trade off. GC provides some value and some costs. Borrow checkers provide some value and some cost. > It only means that the data model doesn't agree with Rust's rules for modeling data (which exist to ensure memory safety in the absence of a GC). I think my initial response was that Rust’s model exist for more than just that single reason. Whether those reasons or trade offs are useful depend on the program in question. In my work I never want a GC, but damn would I love a borrow checker.