On 25/09/2011 3:15 PM, Brian Anderson wrote:

I added the calculation for unique box of pinned recently so that
shouldn't be too hard to change; just need to make sure unique box of
resource is non-copyable. Incidentally, I'm finding the overloading of ~
and 'unique' to be quite difficult to communicate about - I think you're
refering to unique boxes of resource. I also changed [resource] to be
pinned (from shared), assuming that the old calculation was valid for
evecs, not ivecs. Is that correct?

Yes, when I am saying "~resource" I mean "unique box of resource". Sorry.

And yes, [resource] -- that is "ivec of resource" -- should be the same as "unique box of resource".

Both should be shared though, not pinned. That's what the comment says, for the reason that we want to be able to move them. That is, we want to be able to move a pointer-to-a-resource -- not the resource itself -- if the resource lives in the heap. That's what I meant in the second email about "indefinite extent". When a resource lives in the heap we should be able to:

   - Move around a unique-pointer to it, if it's uniquely owned
   - Shallow-copy around a shared-pointer to it, if it's shared-owned

This is the counter-intuitive corner case I keep mentioning. It doesn't *seem* like unique-box-of-resource should be shared -- there's nothing "shared" about it, no refcounts in sight -- but it's correct for it to be "MOVE + NOSEND" in terms of kind-restrictions, which happens to be the same as "shared kind".

Why can't no-move just be no-send, and then make shared types
un-movable? Is there something useful that can be done by moving shared
types (besides saving some refcounting)? The entire (maybe? at least the
biggest) motivation for move is send, and it would be easier to think of
them as the same thing.

If I read correctly, you're suggesting a change so that we have no-move and no-copy bits, and:

  - fn& anywhere, or interior-resource, makes no-copy
  - @, or fn& anywhere, or interior-resource, makes no-move

This seems backwards to me; I consider move to be indivisible "copy + drop", so it's weird that you can't move something if you can copy it.

Further, if you do this, you can't write type-parametric algorithms (say, vec::*) in terms of move if you want them to work on @, so you have to write in terms of copy, which means deep-copy on ~, and failure to work at all on ~resource; exterior resources you want to do anything with parametrically have to be @resource. Deep copying all ~ on library APIs is expensive and unlikely the semantics most callers have in mind; we should be minimizing deep copies and using move/swap as much as possible. In addition to all the refcount traffic on @ by making shallow copies.

Our "heaviest" use of move-semantics is surely to protect against racing by modeling the message-passing system in it; but efficiency is a close second, and not to be ignored.

I'm also not convinced there are not other restrictions inexpressible in this scheme, but haven't done the full list to check..

It seems like resource and fn& are different kind, or at least the kind
system doesn't fully express what can be done with each. For example,
~resource becomes a shared kind which can escape, ~fn& can't be a shared
kind.

~fn& can't be constructed. We syntactically restrict the construction forms of fn&. Or at least we're supposed to be. I'm not sure if we're doing so presently.

I hear what you're saying -- the rules in kind.rs are certainly not "perfectly obvious" -- just, as I said earlier, if you're going to try to revise these rules, be very careful to cover *all* cases. Make an exhaustive list of restrictions to be-able-to-encode first, and make sure you have a way of expressing all those restrictions simultaneously as you work through different ways of expressing the rules. It's tricky.

-Graydon
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to