All variables are supposed to be initialized before use. But a Rust Vec, like a C++ std::vector<T>, has both an in-use "size" and a usually-larger pre-allocated "capacity". This allows adding elements without getting a new memory block.
Implementing Vec safely in Rust runs into the problem of initializing the capacity not yet used. Not initializing it is unsafe, so Vec has to have "unsafe" code.
I'd argue for this:
First, data types should be divided into "fully mapped" and "not fully mapped". A fully mapped type is one where all bit combinations are valid. Fully mapped types don't have to be initialized to be memory-safe. This includes integers, floating point on most systems, but not booleans. (C++ calls this "plain old data", or POD, but allows Booleans and enums. Whether Booleans with values other than 0 or 1, or out of range enums, should be considered "plain old data" is a good question for a language designer.)
If it's not fully mapped (worst case, it has a pointer or reference in it), what do you do about uninitialized data in the unused "capacity" area? If it's not initialized, you have a pointer with a junk value, as far as the language is concerned. If it has to be initialized, you have a problem if initialization requires an input value.
So I'd argue for the concept of a partially initialized array as a language feature. For simplicity, only being initialized from the beginning to a limit (0..N) should be supported. (Yes, there is such a thing as a giant sparsely initialized hash table where allocation info is stored outside the table. See Google's sparse hash table. That's very rare.) The idea is that you designate some field of the structure as the "size", and accessing beyond "size-1" is a subscript error. But you can initialize at "size", and this increases "size" by 1. You can decrease "size" if you own the whole object.
If you have both of those features in a Rust-like language, you should not need "unsafe". Except to call other languages, maybe.
Of course a language and its clever implementation can make reading unintialized values from malloc()‘d objects UB with all that implies, but that’s a spec choice.
So I believe you could define what’s returned by malloc() as safely castable to one or more “fully mapped types”, which would solve the problem for vectors at least of those types.
The problem I was discussing is with growable arrays, where the memory underneath is partially initialized.
I haven't looked at google's sparse hash table yet, I'll have to codesearch that =)
Interesting. Cone has every known approach to memory management. GC, refcounts, arenas, pools, single ownership, thread local... Worth an experiment, but you probably don't want to go there for a widely used language. Think of the library compatibility problems.
For locking purposes, there's an argument for thread-local, shared, and transferable objects. Transferable objects are what you put in a queue between two threads. They're single-thread and don't need locking when in use, but can be handed off to another thread.
It's useful if transferable objects are transferable by copy. This is useful for machines where not all memory is shared. We're headed there; cache management gets harder and harder as the number of cores starts to approach 3 digits. So think ahead here.
I can imagine having programs which are tree-like hierarchies of regions, but I'm starting to suspect we can have directed acyclic graphs, and perhaps even very small cycles in them...
There are three things preventing someone from using the object after destroying it:
Locking goes deep into Vale's concurrency story, but I can try to sum it up: I'm curious about that second safety hole Rust has. I don't think Vale has that same hole, as we initialize every array with a size and a lambda, and there's no opportunity to stop it halfway through (well, our form of "exceptions", involving pure functions or rollbacks, could stop it and keep everything safe), you can see an example in our little roguelike sample [1] on line 415.[1]: roguelike.vale, https://github.com/ValeLang/Vale/blob/9541d414ce6b1c2745de19...