> when using closures you really don't want to be thinking about memory allocation
You don't have to think about this with Rust - and you don't need a GC either. The borrow checker will make sure that your closure doesn't outlive the variables it captures, which is what you need for correctness in this case.
> The borrow checker will make sure that your closure doesn't outlive the variables it captures, which is what you need for correctness in this case.
No, the borrow checker will merely give you an error when your closure may outlive the captured variables. This is often not useful, and is an impediment to being productive. As a programmer you don't want to be solving the same boring problem of memory management over and over again, unless perhaps when you're doing really low-level stuff and there is no other option.
How is it "not useful"? It's generally quite easy to resolve the ensuing lifetime problems: either use .clone() to copy the underlying values, or use Rc<>/Arc<> to provide shared control of the lifetimes involved. And it's far from a "boring problem"; quite often, being aware of how and why lifetime and mutability interact at a "low" level can inform higher-level design as well.
Reference counting doesn't solve all memory management problems. With closures you often end up with circular references.
And yes, in probably 99% of cases you can actually find a way out of a memory management problem in Rust if you think hard enough.
But my point is that quite often you don't want to think about memory management. Rust doesn't help here. Rust advertises that it solves memory management problems, but in reality that only holds up to a point. So use Rust for your OS or your low-level server, but don't think it is a panacea.
> With closures you often end up with circular references.
In that case, you can manually lift the data object involved into a function argument, as opposed to a variable capture - with its ownership being thus managed explicitly. This is generally an improvement in design.
Of course, Rust does only solve memory management problems "to a point"; there are cases where fully general GC is pretty much a necessity. But even most uses of closures - a fairly high-level language feature, all things considered - don't require this in many cases.
You don't have to think about this with Rust - and you don't need a GC either. The borrow checker will make sure that your closure doesn't outlive the variables it captures, which is what you need for correctness in this case.