4 ms·
You're overlooking that Rusts "solution"(borrowing, livetimes, etc. ) is not only solving the same problem that garbage collection tries to solve. Garbage colle
by lordnaikon 9y ago
You're overlooking that Rusts "solution"(borrowing, livetimes, etc. ) is not only solving the same problem that garbage collection tries to solve. Garbage collection is "only" solving the "memory resource problem". Rusts solution is a more general solution to the "general resource problem" .. like file handles, sockets and of course memory and besides that gives you tools to never get bitten by data races. Nothing (besides memory) garbage collection is helping you with. You have to mitigate those problems still in garbage collected languages like Swift, Go, Java, Python (to name a few) and various other solutions to help with this (try with resource, with statement, immutable message passing etc.) Rust tries to give you one solution "to rule them all". Is this better, worse? Idk – nobody does, the Rust people are trying to figure this out :) Nothing is carved in stone. And if you're more productive in another language you should use it! But you can only know by figuring this out for yourself. Rust works well for me – that's no guarantee that you have the same experience. Rust is still hard to learn and one needs to question himself if the effort in learning pays out at the end – it has for me, i guess/hope ;)
- Mouse47 9y ago>Rusts solution is a more general solution to the "general resource problem" It's true. Ever since I got familiar with the ownership concept, I've taken to writing C# IDisposables with disposable member variables like this: public MyObject(){ this.myResource = new DisposableResource(); this.ownsMyResource = true; } public MyObject(DisposableResource resourceToUseThatIDontOwn){ this.myResource = resourceToUseThatIDontOwn; this.ownsMyResource = false; } public void Dispose(){ //not pictured: .NET's boilerplate dispose code if(ownsMyResource) myResource.Dispose(); } For the client I'm contracting with right now, mismanagement of disposable resources is the #1 issue in the codebase. 100k lines of code, and it's never clear who should be disposing connections. There are some objects with multiple constructors (like above) that have 'conditional' ownership. In Rust, it's impossible to have this problem, period...although the above C# construct simulates it, lol.
- cesarb 9y agoFun fact: what you did is a hand implementation of Rust's "drop flag" (https://doc.rust-lang.org/nomicon/drop-flags.html https://doc.rust-lang.org/nomicon/drop-flags.html).
- Mouse47 9y agoThat's pretty cool - it never occurred to me that determining drops required anything other than static analysis. Nice that it doesn't affect the layout of the types, either...which I'm guessing is why they added: >The drop flags are tracked on the stack and no longer stashed in types that implement drop.
- randomThoughts9 9y agoI agree and I appreciate what they are trying to do. But just as a counter-argument, look how a simple lock looks like in Rust [1]: fn main() { let counter = Arc::new(Mutex::new(0)); let mut handles = vec![]; for _ in 0..10 { let counter = counter.clone(); let handle = thread::spawn(move || { let mut num = counter.lock().unwrap(); *num += 1; }); handles.push(handle); } //... } [1] https://doc.rust-lang.org/book/second-edition/ch16-03-shared-state.html https://doc.rust-lang.org/book/second-edition/ch16-03-shared... ----- edit: Just to clarify my point. The ownership model is a beautiful solution to the resource management problem. And as the parent pointed out, some concepts can be cleanly borrowed/reused in other languages. But now, in Rust, in practice, you realize that this model requires a lot of boilerplate code just to make the borrow checker happy, even for simple things like using a lock: create Arc(Mutex(data)); clone the arc reference; move the new Arc reference to the new thread.
- pjmlp 9y agoYou can simulate something like that using lambdas in C#. Something like withLock(counter, (num) => { return num + 1; }); or in alternative, withLock(counter, (ref num) => { num++; }); If C# allowed for trailing lambdas it could look better.
- seanmcdirmid 9y agoYou would still need to have lots of resource management problems to consider using Rust, i.e. it is useful to those high performance/embedded domains that still use C/C++. There are high level dynamic solutions even for things like data races these days (e.g. transacations) if you don’t need to juice every last bit of perf out.
- Gaelan 9y agoGC helps with file handles. Just give the "file" object a destructor that closes the underlying handle.
- vpalanc1 9y ago... and, it will be eventually closed. Maybe. Definitely before the program quits. Not sure that it'll be closed before you run out of file handles, though.