jack: (Default)
[personal profile] jack
Bitwise copy

I'd read this but not really thought about it before. Rust prioritises data structures which can be moved or copied with memcpy. That eases various things. But to achieve it you need to keep a very tight rein on many things which are used all over the place in most languages.

Notably, you can only have a pointer to a struct from one place, unless you specifically arrange to "borrow" it, but a borrowed value can't be changed or moved (either the original or any of the borrows). Rust blogs describe this as similar to the discipline needed when dealing with data from multiple threads, except to avoid mistakes like "I am in the middle of a computation using this value, and then call another function which changes this value, and forgot that created an implicit dependency between those bits of code".

This shows up in lots of confusing ways, like function parameters need to be borrowed or copied, else they are moved by default, and once moved, the original is gone and can't be accessed.[1]

I'm not sure if this will turn out to be really useful or not. I see the logic, and agree that can prevent mistakes, but I don't know if it's possible to write code to avoid those problems, or if in practice everyone ends up using one of the ways to work round this restriction, and then tracks any unfortunate implicit dependencies in their heads just like they used to.

The specific example I'm going to mention below is having owned structs which contain a pointer back to the owner, which doesn't usually work because someone else needs to have a pointer to the owner as well.

Interior mutability

This is only slowly making sense to me, I'm not sure how much sense the version I'm writing does.

A common pattern in some programs is "having a struct containing a bunch of settings which can be accessed and changed from multiple parts of the program".

This is particularly difficult in rust because having different pointers to an object usually forbids you from changing it.

The way round this is "interior mutability", that is, a value that can be changed even if it's part of a struct which is supposed to be immutable. It's a bit like "mutable" in C++ which is used for weird edge cases like caching calculated values in an apparently const class or allowing const functions to lock mutexes, etc. Except that you're apparently supposed to use it for any "normal" variables which you can read and write from multiple places. IIRC you can either use "Cell" which works on a normal value variable in other languages or RefCell which works like a pointer and has a lock at runtime which panics if you get it wrong.

This brings us back to the topic I was thinking about before, originally inspired by these features of rust. That a common pattern is needing a pointer to a owning class from an owned class. But you might not need that if you had the feature I discussed before, that whenever you access the owned object through a reference to the owning object, it carries along a secret pointer to it, like a second "this" pointer.

That could work for the case of "access some central object from several different parts of the program". If various parts are owned objects, that can access the parent object, but only when they're entered by code from that object, the parent object (including the settings object) is only accessed from one of the components at once, which borrows exclusive access to the parent when its member function is called.

However, the feature I wasn't sure of but would need to be added is, if you have a pointer to that owned object from anywhere *else* (notably, a callback of some sort), it needs a special pointer that wraps up a pointer to it and a pointer to its parent together. That does sound really hairy, although if you have a 64 bit pointer there should be lots of room to implement the sordid details somehow. Assuming you never need to nest this too deep. Although of course, at that point, you've given up any pretence these could be moved around in memory anyway, so maybe there's no benefit to this flexibility?

Footnotes

[1] I think explanations of this explain it really badly, in that most people encounter these errors before understanding why "move by default" is a thing at all, so don't find that a satisfying answer.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org

Active Recent Entries