On Friday, 13 July 2018 at 17:12:26 UTC, Atila Neves wrote:

Rust can do that because it enforces it at compile-time. A D solution wouldn't be able to do anything more with immutable borrows.

Hmm, thinking on this a little more...it does seem difficult...but I don't think the problem is with immutable borrows. I think the issue is with the exclusivity of Rust's borrowing.

D's immutable is transitive so if you're using immutable at some point, then no one else can modify it anyway. So you should only be able to immutably borrow something that's immutable anyway.

Rust, by contrast, allows immutable borrows of mutable data. In some sense what Rust does corresponds more to const (or maybe head const), but it's more than just const. A Rust immutable borrow of mutable data prevents the mutable data from being modified during the borrow. The Rust example below involves an immutable borrow of mutable data, but it fails to compile because you modify x while it is borrowed. If you put y in a separate scope, then it compiles because x is no longer being borrowed after y exits the scope.

fn main() {
    let mut x = 5;
    let y = & x;
    x += 1;
}

This exclusivity also affects mutable borrows as well. Below does not compile because y controls x. Rust's mutable borrows are also exclusive. Only one is allowed at a time. So that same trickiness is applied here.

fn main() {
    let mut x = 5;
    let y = &mut x;
    x += 1;
}

The only thing that made sense to me about implementing this at compile-time was a template parameter that could disable things like opAssign.
https://run.dlang.io/is/FvJvFv
But being able to change the template parameter is tricky. You can cast it at run-time, but other that that it's beyond me.

On a separate note, I didn't have any success working with automem and const/immutable types.
https://run.dlang.io/is/el4h3e

Reply via email to