5 ms·
I disagree. It is substantially and unequivocally better to hold onto memory until the end of scope than to leak memory by default. How can anyone argue that le
by coder543 4y ago
I disagree. It is substantially and unequivocally better to hold onto memory until the end of scope than to leak memory by default. How can anyone argue that leaking memory is a better default? That’s a ticking time bomb. Maybe someone is so optimistic as to believe they’ll catch every leak before shipping new code?
You can easily add a manual “drop” call in Rust at any point if you want to force an allocation to be freed sooner, but I speak from years of experience using Rust for work when I say that Rust’s RAII model is not problematic in practice. I’m not simply speculating or theorizing, and I have professional experience with a variety of languages at all levels of the stack. I personally don’t mind garbage collectors most of the time, but Rust is great when you need more control.
In C++, RAII can absolutely be problematic because you are able to easily do things that cause undefined behavior by accident, which is arguably worse than either leaking by default or the mere act of holding onto memory for the duration of a scope.
If you can propose a system which cannot be contrived to have any downside, that would be fantastic! In the real world, Rust’s approach to memory management is extremely pragmatic and beneficial. I’m sure someone will eventually improve on Rust’s approach, but “leak by default” isn’t it.
I honestly do enjoy following Zig… it is a fascinating language taking a really interesting approach to solving many problems, but its memory safety story is not where I want it to be yet. Leaking memory by default is technically safe, but it's not exactly endearing.
- varajelle 4y agoOf course you can call drop() manually, but almost nobody does or even think about it because that's not the way you program in a language with RAII. Don't get me wrong. I do think that rust and c++ RAII is much more convenient and safe than the C or Zig way. (I'd even prefer if you could annotate given struct in rust so the compiler could drop them as soon as it's no longer used, but that s not that simple)
- coder543 4y agoI definitely wish that Non-Lexical Lifetimes would eagerly drop anything that doesn't implement Drop. It would probably be a breaking change to automatically call an explicit Drop implementation anywhere other than the end of the current scope, so I think that would have to be left as-is. String doesn't implement Drop, so it could easily be dropped eagerly within the scope as soon as it won't be referenced again. Such a change would be roughly equivalent to any of the compiler optimizations that reorder statements in ways that should be unobservable.
- ______-_-______ 4y ago100%. I would actually go further and say every value should be dropped immediately after its last use, including temporaries in the middle of statements, whether or not it implements Drop. Reuse the same rules that NLL uses. Breaking change yes, so do it next edition. It would lower memory usage in general and solve so many little pain points, not least of which is holding strings across await points.
- varajelle 4y agofn foo(xx : &Mutex<String>) { let lock = xx.lock(); let ptr = &mut *lock as *mut String; unsafe { use_from_c(ptr) } } You get the idea: you don't want the lock or the string to be dropped before the unsafe code, even if the actual string is no longer used. That's the breaking change. It's hard to detect automatically, so hard to justify even in an edition.
- coder543 4y agoI generally agree with you (which is why I made an exception for values with a manual Drop implementation), but to advocate on behalf of the idea… I don’t think it would be too crazy to make a rule that any function that invokes “unsafe” (or is itself defined as an unsafe function) would fall back to the old scope-based drop rules. Worst case scenario is that you’d be dealing with the current level of memory usage efficiency, and you might need to manually call drop if you want something dropped earlier, but in most cases things would be eagerly dropped even sooner. Outside of uses of unsafe, are there any other serious problems with eagerly dropping values that manually implement Drop? Maybe this fallback mechanism would also have to be invoked simply for casting to a raw pointer anywhere in the function. Either way, a list of exceptions to eager drop would arguably be better than not having eager drop, as long as the list was sound. It would still be a breaking change, and would definitely require at least being restricted to a new edition. Some people currently use Drop as a kind of scoped “defer”, especially for things like instrumentation, so maybe it would be time for the language to introduce a proper “defer” statement that exists for that purpose instead of making Drop so lazy for everyone.
- vrfvr 4y agoI still don't get why one should do that in the first place
- guidoism 4y agoI’ve recently been writing personal code that leaks like a sieve. It’s just not worth my time to find every leak when the lifetime of the process is finite and short and it will only ever run on a machine with gigs of memory. I haven’t thought through your question enough but maybe a situation where memory usage would be super high if waiting until the end of scope? I’m probably trying to hard to come up with a situation but I have a gut feeling that freeing mid scope is important under certain circumstances to keep the code simple and understandable.
- coder543 4y ago> I’m probably trying to hard to come up with a situation but I have a gut feeling that freeing mid scope is important under certain circumstances to keep the code simple and understandable. I explained in my previous comment that you can explicitly "drop" any value at any time in Rust, if you choose.[0] But if you don't, it will still be dropped at the end of the scope. The developer has control, but the language will watch your back. [0]: https://doc.rust-lang.org/std/mem/fn.drop.html https://doc.rust-lang.org/std/mem/fn.drop.html
- StefanKarpinski 4y agoHeck, this is the entire memory management model of PHP, which I found shocking when I learned it, but makes sense given that the language is intended to generate web pages: just allocate, never reclaim the memory, then kill the process when you’re done.
- coder543 4y agoDo you have any sources? Maybe some truly ancient version? PHP has done garbage collection (seemingly mixed with some reference counting, like Python) for at least 10 or 15 years... I didn't bother to keep searching for even older information, but nothing I saw indicated that PHP only released memory when the process for a request exited. I don't even think most mainstream uses of PHP have done the process-per-request model for decades, but I could be wrong.
- 4y ago