Vale brings a lot of innovations to the table to make coding safe.
All of today's native languages have some unsafety in them. For example, in C, you can bring in a library that causes mysterious crashes in other parts of your program, because there are no protections in C.
Rust does especially well here, though its guarantees are violated by its unsafe keyword. Most think that memory unsafety can only happen inside unsafe blocks, but unfortunately, it can cause memory unsafety outside, in safe Rust as well.
Vale uses hybrid-generational memory, which doesn't require any unsafe, even in its standard library.
Vale goes even further, by not allowing any unsafe code. Even if we call into C, there's no way to trigger memory unsafety in Vale.
Vale conceptually destroys and recreates any object that we send to another thread. 0
When the programmer doesn't want to conceptually destroy and recreate an object, they can use a mutex, and have the region borrow checker to guarantee safe handling.
Vale can call into C code (and vice versa). So how does it maintain its safety guarantees? By using what we're calling extern isolation.
The behavior when sending an object into C depends on the object's mutability. 1
When Vale's package manager is ready, the user will have to whitelist every single dependency that wants to call into extern code.
This way, we can be more certain that none of our dependencies are making surprising extern calls.
Often memory safety comes at a cost:
With Vale, we weren't content with these tradeoffs, so we augment single ownership with constraint references, which make sure we don't destroy an object that someone still expects to be alive. See The Next Steps for Single Ownership and RAII for more on these.
This isn't as expensive as one might think. We use a combination of assertions and generation increments to guarantee no further accesses from the source thread.
As described in Structs / Mutability, a struct can either be mutable or immutable.