Just to clarify, Valen's borrow checker can express shared-xor-mutable, its value proposition is that it can _also_ express mutable aliasing (with `in`).
* When a function has a mutable effect into a group, and the function doesn't declare any other groups to alias it (with `in`), it is effectively a unique reference.
* When a function has references into a group, and it declares no `mut` effects into any of them, they are effectively shared/immutable references.
This helps with Valen's structured concurrency in particular, but also helps guard against the single-threaded race conditions in the same way that Rust's borrow checker does. It also helps with Rust interop!
So, TL;DR: Valen lets you choose between shared-xor-mutable and mutable aliasing.
Also note how mutable aliasing is opt-in (via `in`), so there's a subtle influence pushing people towards shared-xor-mutable, so that they only reach for mutable aliasing when it will benefit them.
> Just to clarify, Valen's borrow checker can express shared-xor-mutable, its value proposition is that it can _also_ express mutable aliasing (with `in`).
Just to clarify, Rust's borrow checker can express mutable aliasing via interior mutability (i.e. UnsafeCell<T> and the various Cell<T> types). A &Cell<T> reference is essentially a mutably aliased reference. The goal is exactly that people "only reach for mutable aliasing when it will benefit them". Of course, any ergonomic improvements around the Cell types are quite welcome, especially if they help C/C++ interop - provided that they're proven to be as sound as the existing borrowck.
Good catch, and well said. Another good example I like citing is GhostCell, which adds mutable aliasing to Rust in a way that's even more flexible than Cell.
I would say Valen's real benefit here is in making a more ergonomic way for functions to work with an arbitrary number of GhostTokens / brands, and to track the relationships between them. (But I admit, I'm no expert with GhostCell, happy to be corrected by someone here)
AIUI, the main limitation with &Cell<T> is (1) no provision for concurrency, obviously - though the various Atomic* types work similarly via interior mutability; and (2) data has to be read, written or modified as a single operation - any provision for enabling subobject access or the like is quite ad hoc, and has to be implemented for the specific type you're working with. GhostCell (and QCell, LCell etc.) generalizes this by tracking the use of shared references at compile time, such that writes will not overlap with each other or with reads, without enforcing a "get/set in a single step" workflow.
> any provision for enabling subobject access or the like is quite ad hoc, and has to be implemented for the specific type you're working with
There is ongoing work on a language feature ("field projection") that could alleviate this.
I think OP understands that.
And I think OP's point, more succinctly, is that Valen programs will be much more difficult to parallelize than Rust programs.
It's shockingly easy to make a single-threaded Rust program use all the cores on a machine by slapping in Rayon wherever you have a Vec. Because Rust forces you to do the hard work of proving shared^mutable before getting a single-threaded program running.
The ecosystem-wide consequence of this is that pretty much every compute-intensive program written in Rust (that doesn't rely on non-Rust libraries for compute-intensive stuff) is automatically multicore. This is one of the reasons why Rust programmers seek out Rust libraries first. Because they know they won't get the unpleasant surprise of putting in a lot of work to adopt a library and then get burned when they find out it will only use a single core.
Apologies for not understanding. And I admit, it's hard to communicate in the abstract, so I might still not understand the question.
If it helps: AFAICT, Valen's borrow checker preserves the same ecosystem-wide concurrency benefits that Rust has. For precedent, check out GhostCell [0] which is not only _compatible_ with Rust's concurrency but gives it some interesting new abilities. Valen's approach could be thought of as a more ergonomic form of GhostCell that better tracks the relationships between multiple groups (brands).
I could give a better answer if we had an example to toss around where we think Valen might force things to be single-threaded.
Rust needs shared xor mutable in order to prevent data races on non-atomically accessed data. You said that Valen can _express_ shared xor mutable, but perhaps you haven't clarified whether this also interacts with equivalents to Rust's Send and Sync to enable the same fearless concurrency.
I mean the article doesn't talk about this aspect of the language, but Send and Sync are orthogonal to borrow checking. I don't see why you couldn't use Rust's exact design in Valen.
How widespread are locks in typical Rust code?
Very rare compared to C code.