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