Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It's similar to Rust's transfer of ownership. Rust is compiled so you get a compile time error if you try to access something you can't access anymore.

Check the code at http://rustbyexample.com/scope/move.html and run it (inside the page). There is a commented out println towards the end. Comment it in, run the code again and see the compiler error.

More about transfer of ownership at https://doc.rust-lang.org/book/ownership.html



I already know very well how Rust works. What I'm not convinced of is that ownership can be correctly and efficiently enforced purely by runtime mechanisms. (Presumably Ruby's implementors aren't interested in introducing static checks anytime soon, right?)

For example, how would you transfer ownership of a big linked data structure from one guild to another?

(0) In Rust, this is as easy as handing ownership of the root node (an O(1) operation) to another thread. Ownership is transitive: whoever owns the root node also owns whatever the root node owns.

(1) In Ruby, I don't see how transitive ownership could possibly work. If I understand the proposal correctly, every object is owned directly by a guild, never by a parent object. Thus, you would have to traverse the entire linked data structure to transfer ownership of every node. This is O(n) work. Making things worse, you would have to make sure that the ownership transfer is atomic - no other part of the program should see the data structure in a “partially transferred” state.

Another example: Say you initially have a guild with three objects, Foo, Bar and Qux, where Foo and Bar point to Qux. If I transfer ownership of Foo, should Qux be transferred as well?

(0) In Rust, the type system forces me to explicitly distinguish between the following possibilities:

(0.a) Foo exclusively owns Qux, and Bar merely borrows it. In this case, Foo and Qux are frozen, and thus can't be transferred until Bar's borrow ends.

(0.b) Bar exclusively owns Qux, and Foo merely borrows it. In this case, transferring Foo doesn't change the fact Qux is owned by Bar.

(0.c) Foo and Bar jointly own Qux (using an Arc). In this case, transferring Foo doesn't change the fact Qux is jointly owned.

(1) In Ruby, what exactly should happen here? Have these guys really thought about the possibilities?


> Thus, you would have to traverse the entire linked data structure to transfer ownership of every node. This is O(n) work.

Correct.

> Making things worse, you would have to make sure that the ownership transfer is atomic - no other part of the program should see the data structure in a “partially transferred” state.

Correct. Guild::Channel#transfer_ownership() does it.

Basically, share big linked data with multiple threads is difficult (simply we need to lock every access).

> Another example: Say you initially have a guild with three objects, Foo, Bar and Qux, where Foo and Bar point to Qux. If I transfer ownership of Foo, should Qux be transferred as well?

Foo -> Qux; Bar -> Qux

Yes, Qux also moved. Programmer can know by "exception" when accessing Qux via Bar after transfer.

This "realization" is the key of Guild. On threads, we can't realize that Qux is shared mutable.


Thanks. This clarifies a lot of things.


> For example, how would you transfer ownership of a big linked data structure from one guild to another?

Slowly.

Objects well-suited to transfer would be shallow mutable structures with immutable data "underneath". Immutable data can be shared, so they'd be ignored by the transfer logic.

Another approach likely to be common would be not transferring objects at all, but sending proxy objects to other guilds which transparently marshal method invocations between those guilds and the object's home guild. For large mutable complexes which are intertwined with everything a guild does, that's probably a more manageable approach.

> Making things worse, you would have to make sure that the ownership transfer is atomic - no other part of the program should see the data structure in a “partially transferred” state

This is easy. You just run the transfer operation with the guild's mutex locked. No other guild can have a reference to a mutable object, and an immutable object doesn't need to be transferred.

> In Ruby, what exactly should happen here? Have these guys really thought about the possibilities?

It seems obvious that every linked mutable object is invalidated, so Qux will be transferred.


> Objects well-suited to transfer would be shallow mutable structures with immutable data "underneath". Immutable data can be shared, so they'd be ignored by the transfer logic.

How often are data structures designed like this in Ruby?

> Another approach likely to be common would be not transferring objects at all, but sending proxy objects to other guilds which transparently marshal method invocations between those guilds and the object's home guild.

What if said “home guild” ends up overburdened with requests coming from all over the place?

> This is easy. You just run the transfer operation with the guild's mutex locked.

You mean both the sender and the receiver's mutexes? I'm worried about the receiver being able to observe partial transfers.


The object graph would only be handed to the receiver once it's fully transferred I would imagine.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: