upvote
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.

reply
> 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.

reply
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)

reply
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.
reply
> 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.

reply
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.

reply
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.

reply
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.
reply
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.
reply
How widespread are locks in typical Rust code?
reply
Very rare compared to C code.
reply
The more you restrict the safe subset of the language, the more correct programs must use the unsafe subset. The logic of "there could be bugs here, therefore it's safer to restrict it" ends in an empty safe subset. The reason for spatial and (to a somewhat lesser degree) temporal memory safety even at the cost of excluding programs that don't violate them is that out-of-bounds access and UAF are extraordinarily overrepresented as causes of severe security vulnerabilities, but that's not the case for concurrency. There are more common causes of vulnerabilities that aren't caught by Rust's type system, that focusing on races seems arbitrary.
reply
> "fearless concurrency"

That saying does more harm than good, and it counts against the Rust community that it keeps repeating it. Deadlocks are not something that Rust prevents. On the contrary, many beginners to Rust often run into deadlocks, some even spurred on by trying to satisfy the borrow checker. An infamous example is https://fasterthanli.me/articles/a-rust-match-made-in-hell . Instead of making blatantly false claims and causing newcomers to Rust frustration, pain and bugs, the Rust community should warn about concurrency and direct beginners to learn about concurrency, both generally as well as specifically in Rust.

reply
* Deadlocks, memory leaks, infinite loops, etc. are all the sort of risks that Rust doesn't try to protect from. In my opinion it's okay to talk about "fearless concurrency" despite deadlocks in the same way it's okay to call Rust memory-safe despite memory leaks.

* Rust's type system also allows you to make safe interfaces like Rayon that do genuinely allow for "fearless" concurrency in a way that I don't really see in other general-purpose languages.

reply
[flagged]
reply
I'm not part of "the Rust community". I'm not sure why you have to be so inflammatory.

Those are bullet points.

reply