Join the discussion
Write your take first — we'll ask for email only when you're ready to publish.
- Hacker News
- Neat!
I have a question about immutability. In Rust, if I have a shared reference to T (an &T a variable or a parameter), then I have a restriction that I can't modify T or anything in it (which Valen thinks is annoyingly restrictive, and I tend to agree), but I also have a promise that no one else will modify it. The latter is quite nice: it makes the optimizer happier (improves aliasing analysis), makes threading happier (nothing descended from the reference can have data races while the reference is alive), and makes me happier (I don't need to think about descendent values being mutated).
Valen can call into Rust, and I think I can see how, at the site of any particular call, Valen can tell that no one is mutating the referent or its descendents: in a single-threaded world, the only thing executing is the current line of code or a maybe a few consecutive lines of code, and the compiler can see the function's signature and any mutable references therein, and if there is no permission to modify a descendent, then it doesn't get modified.
But in a multithreaded world, especially if calling into Rust in a thread, doesn't there need to be a way to guarantee the immutability of an object across an entire region of code? How does that work in Valen?
And for making immutability more comprehensible to people and to local analysis in general, would a special type of reference meaning "yes, this one really is fully frozen and there are no mutable paths into it for the entire lifetime of this reference" be a nice feature?
(Aside: I've occasionally contemplated whether Rust would benefit from another flavor of reference: no-access. A no-access reference would guarantee the referent's existence but could coexist with shared and with mutable references. Safe code would be unable to read or write through such a reference. Other than making some cell-like types mildly less mind-bending, I'm not convinced I have an actual justification for this thing. This would give Rust three flavors of references.
But I can imagine a Valen-like language having three flavors of references: frozen references (cannot use them to mutate and there's a promise that no one else can either), exclusive references (fully mutable, etc, just like Rust's &mut) and flexible references (the kind of reference in the blog post).)
by amluto - I wonder if nowadays we should be focusing less on scalar data structures and more on languages that facilitate vectorized/SIMD instructions. Languages like Vx lang, Mojo, and Futhark that work both in the CPU or the GPU, although each one works in a different level of abstraction and control.
- Also, as I was writing this, a couple things occurred to me:
* We _could_ use the function parameter syntax `entities: &world.entities[]` instead of `entities in world.entities[]`.
* "Groups" aren't really central to understanding the idea, so Path Borrowing might be a better name than Group Borrowing.
Opinions welcome =)
by verdagon - It sounds more like "path" borrowing than "group" borrowing to me, but the idea is great! Quite eye opening!
One minor thing is that I'm not sure why they had to have "in" keyword for sub-borrows. Wouldn't it be more consistent to see "entity &world.entities[?]" instead of "entity in world.entities[]"? We'd consistently get the borrow "&" symbol and open the door for some contracts on what index (range) is affected.
by kvark - > It's part of my eternal quest to find the memory safety holy grail: something as powerful as Rust's borrow checking, yet something as simple and flexible as reference counting or garbage collection.
I'm definitely hoping you succeed. I'd love to be able to write a small language (maybe that didn't do absolutely every last thing you can do in Rust, but was ergonomic and easy to use) that had a borrow checker and didn't require writing a nuclear reactor.
by dualvariable - > Borrow checking has the "shared-xor-mutable" restriction: if you hold a reference to an object, nobody else can change the object.
The article makes this sound like a problem. It isn't. This restriction frees you from thinking about certain classes of bugs in concurrent code; it's where the "fearless concurrency" comes from. R^w isn't about lifetimes - you could, in spirit (not sure about practice), remove it from Rust without affecting use-after-free at all.
Of course, it means you can't write many completely valid programs, and so we'd hope there's a better solution, but removing it is not one.
If you want to have to think about that (and potentially introduce bugs), that's perfectly fine. The flexibility of not requiring r^w is extremely useful. I'm just clearing up this mis-attribution.
by zamalek - > the compiler remembers where a reference points to
> So we spent months sharpening the explanation and figuring out its benefits, and wrote a post 8 on it last year, hoping other languages would pick it up.
My language (see my submissions) has this feature since many years. In its current form it exists roughly since year 2020, but some under-the-hood changes and slight improvements have been done since.
by Panzerschrek - The ability to hold a reference to a container and its member seems to be interesting. But I don't think it adds significant value in practice (behind some synthesized examples) and doesn't worth to increase language complexity language compared for a more coarse reference analysis (variable-based).by Panzerschrek