10 karma · joined October 31, 2016
So, with the understanding that "borrowing" means "locking others out", a group parameter borrows the group for the duration of the function call. If it borrows the group as mutable, no other group parameters can borrow the group. If it borrows the group as immutable, other group parameters are limited to borrowing the group as immutable. This is reminiscent of the Rust model, but the XOR rule applies to group parameters rather than references, and borrowing lasts the duration of a function call, rather than the lifetime of a reference.
For example, an Intel CPU won't reorder `x += 1` and `x *= 2`.
I wrote a more detailed answer here: https://news.ycombinator.com/item?id=45057636
I suppose you could describe the differences from Rust as follows:
- Borrowing happens for the duration of a function call, rather than the lifetime of a reference.
- We borrow entire groups, rather than individual references.
The latter trick is what allows a function to receive mutably aliasing references. Although it receives multiple such references, it only receives one group parameter, and that is what it borrows.
Hope that makes sense!
That said, there is still hope! I have been iterating on the design over the last 9 months and am fairly confident that I can model graphs, as long as a few restrictions are imposed, such as not being able to delete nodes. But I can't prove this will work yet, so we will need to wait and see what the next design iteration looks like. I'm fairly confident that the next iteration will be more powerful than the version presented in OP's blog post.
This isn't true in most cases. If every subtree is only referenced by its (unique) parent, then you can use a standard Rust "Box", which means that during compilation, the compiler inserts calls to malloc() (when the Box is created) and free() (when the Box goes out of scope). There will be no reference counting — or any other overhead — at runtime.