[rust-dev] Vectors, mutability & vec::dedup

Graydon Hoare graydon at mozilla.com
Thu Dec 13 10:52:23 PST 2012

On 12-12-13 12:17 AM, Tom Lee wrote:

> It looks like the 'move' operations here are directly modifying the
> contents of the vector by moving data around in the vector. This
> strikes me as kind of strange. I've allocated an immutable vector on
> the exchange stack and so make the assumption that the contents of the
> vector is in effect fixed. Is that assumption cast to the wind as soon
> as I start working with a mutable, borrowed pointer to that same
> vector?

More or less. Mutability "inherits" (not sure I love that term, but it's
what we're using) along the ownership path to a memory cell. So while --
operationally -- you and I both know that there's a difference between:

   // "Mutating a cell in a vector"
   foo[0] = 1


   // "Mutating the vector variable"
   foo = [1] + foo[1..]

The _observational_ difference, on an owned value (i.e. you're the only
person who can even see the vector in question) is really just that the
latter would do a bunch of allocation, copying and freeing, and wind up
pointing to a different place containing exactly the same result. From
the perspective of the surrounding code, if it's not actually paying
attention to pointer values, those two lines are identical.

So after much struggling with library idiom evaluation, we decided that
differentiating the two in the type system was more cost than benefit --
it meant we had to have two different paths for a lot of code that
differed only in where the obligatory word 'mut' showed up -- and
rearranged mutability so that it "inherits" through the ownership path.
That brings with it the significant benefit that we can often toggle the
mutability from the entire datatype by assigning it to a read-only or
read-write owner.

> Or is this just the consequence of a bit of a sleazy optimization,
> where the function signature makes it *look* like we're going to
> return the deduped result in 'v' when in fact we're modifying it
> in-place?

More or less. One person's sleazy optimization is another person's
essential one. De-dupe might be a bit surprising but for a lot of
operations (mostly vector operations -- it's the "arbitrary size" type
after all), doing them "in place" is the difference between acceptable
performance and "ugh, I'll just go do this in C". Our goal is to
minimize the number of cases where users feel they have to switch to C
"for performance reasons".

> I'm not sure there's a coherent question here, but I feel like I'm
> missing something. Hopefully somebody can understand what I'm rambling
> on about & shed some light :)

Rambling questions -- so long as they're not too hostile! -- are good.
They point out a need for docs that clarify and make-explicit. We'll
need a lot more discussion about this in the docs eventually. Keep
pointing out things that don't make sense and we'll try to make sure
they're well covered.

(And just as likely someone who can explain this better will tell me I'm
mis-representing it now, and we'll all learn something!)


More information about the Rust-dev mailing list