News for hackers. Stuff that matters.
Re:Algebraic Effects, Ownership, and Borrowing by rayiner on Wednesday February 21, 2024 @01:56PM (#39457919)
The author’s other blog post is also interesting, highlighting some of the complexity in Rust arising from tying together the concepts of shared references and immutability: https://antelang.org/blog/safe_shared_mutability/ (I.e. in Rust, mutability precludes shared references, even when it would be safe, such as when those references could not be shared across threads.)

Getting rid of explicit lifetime variables is also an interesting choice within this design space.

Re:Algebraic Effects, Ownership, and Borrowing by Georgelemental on Wednesday February 21, 2024 @02:42PM (#39458505)
Rust chose to tie these together for a reason: https://manishearth.github.io/blog/2015/05/17/the-problem-wi...
Re:Algebraic Effects, Ownership, and Borrowing by qouteall on Wednesday February 21, 2024 @09:00PM (#39462209)
Alias-xor-mutability is useful for interior pointers (referencing into an enum, referencing into a Vec) because modification may change the memory layout and invalidate the interior pointer. But when the memory layout does not change in singlethread case, alias-xor-mutability can reject safe programs.
Re:Algebraic Effects, Ownership, and Borrowing by zozbot234 on Wednesday February 21, 2024 @09:35PM (#39462472)
I don't understand what "singlethread case" means here. If you mean that only a single reference is active at any given point of the program, Rust allows you to make that a mutable borrowing. If multiple aliased references are active, then you don't really have a "single thread" of control, and modifying one reference may invalidate assertions made by others (even something as simple as n != 0 prior to a division, or n < array_size after a bound check). Shared mutable state must be signaled very clearly if you want to keep a sensible semantics, and Rust does this with the Cell<>, RefCell<>, Atomic* etc. constructs.
Re:Algebraic Effects, Ownership, and Borrowing by jfecher on Thursday February 22, 2024 @05:43AM (#39465352)
Hi, author here!

If anyone's curious, here's how ante addresses these issues:

- It causes memory unsafety: Ante's `shared` references prevent memory unsafety by preventing projecting them into "shape-unstable" types like a vector's element

- Iterator invalidation: This is the previous point in disguise. Since iterating over a shared vector would grab references to its elements - this is prevented since it is shape-unstable. You'd need to clone the elements.

- It's effectively threaded: This is the same bug yet again! Once shared-ness is tracked this becomes a non-issue. Ante is still able to have the static guarantee that this can't happen but does not need to prevent sharing to do so.

- Safe Abstractions: This section is a bit general but it's worth noting Ante still has the ability to have `&own mut t` references if needed. The `swap` function there could use them for example.

Overall the claim that "Aliasing that doesn’t fit the RWLock pattern is dangerous" is fairly rust-centric. It would be dangerous if you had no other restrictions, but we could also adopt different restrictions that still permit aliasing but disallow projection into shape-unstable types instead.

Re:Algebraic Effects, Ownership, and Borrowing by foldr on Wednesday February 21, 2024 @02:52PM (#39458615)
>such as when those references could not be shared across threads

Shared references can be problematic in a single threaded context too. (You may well be aware of this, but posting for the benefit of anyone who isn't.) This blog post has a good summary of the problematic cases: https://manishearth.github.io/blog/2015/05/17/the-problem-wi...

Re:Algebraic Effects, Ownership, and Borrowing by SkiFire13 on Wednesday February 21, 2024 @05:00PM (#39460238)
Rust does have something equivalent to what's described in the article you linked (and in fact the article even cites it): `&Cell<T>`. It does have some drawbacks compared to what's described in the article though (e.g. no built-in field projection, but it can technically be added in a future compiler version). It is also not completly free: it requires custom implementations of `Clone` to be `unsafe` (in Rust this is equivalent to the fact you cannot clone the `T` inside a `&Cell<T>`, this could also be fixed with an `unsafe trait`). Overall the idea is nice though and I'm curious to see how it will turn out in practice.
Re:Algebraic Effects, Ownership, and Borrowing by Rusky on Wednesday February 21, 2024 @08:02PM (#39461796)
Ante has a similar unresolved problem with Clone- AIUI you can only safely Clone things you can project a `&shared` reference through.
Re:Algebraic Effects, Ownership, and Borrowing by SkiFire13 on Thursday February 22, 2024 @02:45AM (#39464337)
To be clear, when I was talking about custom implementations of clone being `unsafe` I was referring to Ante. Ruat currently doesn't have the equivalent of Ante's `Clone` (but it could)
Re:Algebraic Effects, Ownership, and Borrowing by Measter on Thursday February 22, 2024 @06:38AM (#39465701)
That article gives an example of where mutable aliasing isn't always dangerous:

    let mut my_tuple = (1, 2);
    let first_elem = &my_tuple.0;

    // error[E0506]: cannot assign to `my_tuple` because it is borrowed
    my_tuple = (3, 4);

    println!("{first_elem}");
In that specific example it isn't a problem because the type being changed is just an integer. But if you tweak it slightly it creates a use-after-free:

    let mut my_tuple = (vec![1, 2, 3], 56);
    let first_elem = my_tuple.0.as_slice();

    my_tuple = (vec![4, 5, 6], 23);
    println!("{first_elem:?}");
In this case `first_elem` is a `&[i32]`, and when `my_tuple` is reassigned the allocation is freed while the reference still exists.