4 ms·
I don't understand what you have in mind. Here's some basic JS, iterating over elements of a Node: for (let child of getElementById('parent').children)
by ridiculous_fish 4y ago
I don't understand what you have in mind. Here's some basic JS, iterating over elements of a Node:
for (let child of getElementById('parent').children)
func(child)
The equivalent in Rust is "risky" because func might also call getElementById('parent') and then that would panic.
I think you are saying that Cell solves this by temporarily moving all children into a local, iterating over that, and then add them back as children? That seems pretty sketchy to me, you have these weird transient states where Nodes are temporarily removed from the DOM.
- Rusky 4y agoNo, I'm talking about matching JavaScript's memory layout and memory management, indirection and sharing and all. The children field is itself a reference to a collection. Reading the field creates a new reference to the same collection, and that is what the for loop holds. If func grabs parent that's fine, it's just one more reference (in the Rc sense). That collection also just holds references, and the for loop copies them out too. The trickiest bit here is the iteration state itself- you wouldn't be able to use e.g. Rust's typical slice iterator and still retain the ability to mutate the collection, but JavaScript doesn't do that either. Its iterators just have to be implemented taking the possibility of external mutation into account. The fundamental tradeoff here is that JavaScript simply puts everything behind a reference, all the time, while Rust allows you to work with objects directly. This is what makes sharing+mutation feel so simple in JavaScript- anything you can do to change the "shape" of a data structure is really only changing a reference, and leaving the old version around in case anyone else was still using it.
- ridiculous_fish 4y agoThank you, that clarifies the idea for me and it's an interesting approach. It seems like an "all in" design that you might apply to e.g. an interpreter. Of course in practice we don't abandon Rust's slice iterators to achieve basic observers or backreferences, and I've definitely tripped over "someone else is already borrowing this thing" runtime errors.