4 ms·
Your suspicion is wrong. It has benefits for parallelism, but is critical for ensuring safety of the more predictable (vs GC) Rust/C++ style of "manual" memory
by dbaupp 9y ago
Your suspicion is wrong. It has benefits for parallelism, but is critical for ensuring safety of the more predictable (vs GC) Rust/C++ style of "manual" memory management.
When one doesn't have a pervasive GC to dynamically clean things up, things still need to be freed but have to be freed in static locations (either explicit free calls in C or end of scopes in Rust and C++). Making this safe means defending against pointers becoming dangling which Rust does by restricting mutation. This restriction translates into some things that can't be copied, such as mutable references (that can lead to iterator invalidation and use after free, among every other undefined behaviour).
In other words, explicit/scope-based freeing being unsafe means the only way to safely manage memory is a garbage collector (tracing or reference counting), which limits how many programs can be written that are verified-safe by a computer. I believe Ada takes the approach you suggest, but this limits it to be most useful for programs that don't allocate (or only do O(1) allocation during startup).
Affineness also allows modeling things like session types better, letting programmers construct their own APIs that defend against mistakes.
You could, and people have, argue that some types could be "autoclone", as in, have `clone` calls automatically inserted where necessary, but when it is raised, a lot of people express dislike because they feel it will encourage slow code and mean people aren't guided towards the (usually) better solution of using references.
- weberc2 9y agoI understand not copying mutable pointers; I don't understand preventing copies of pointers to immutable data. I also don't see why affine types allow rust to get away without a GC in a way that scoped-based memory doesn't.
- steveklabnik 9y ago&T is Copy, so I'm not sure what you mean with the first bit. For the second one, consider Box<T> vs uniq_ptr<T>; Rust can statically prevent use after-move, C++ cannot, and you'll get a NPE. That is, you can totally get rid of a GC through only RAII, but you can't guarantee memory safety (as far as we know!) without affine/linear types.
- dbaupp 9y agoTo be clear, Rust does scope-based memory management and does allow copying pointers to immutable data. Affine typing (plus the rest of Rust's system) on top of scoped memory management is needed to avoid problems like returning a pointers into something that is deallocated at the end of a function: int &foo() { std::vector<int> v = ...; return v[0]; } // return value is dangling And similarly, avoiding having pointers into things that are destroyed when their parent is modified: std::vector<std::unique_ptr<int>> v = ...; int &ref = *v[0]; v.clear(); // ref is dangling