On Wed, May 1, 2013 at 5:37 PM, Vadim <[email protected]> wrote:
> Thanks for your response Niko.  A couple more questions if you don't mind:
>
> On Wed, May 1, 2013 at 10:51 AM, Niko Matsakis <[email protected]> wrote:
>>
>> Hello,
>>
>> Unfortunately, I accidentally deleted a message from Vadim that I
>> wanted to reply to. However, it had strayed from the topic of the
>> thread anyhow (which was called "sub-grammar for range pattern
>> constants") so I'll just startup a new thread here.
>>
>> Vadim wrote:
>>
>> > - Does "immutable" mean that the referenced object cannot change
>> > forever, even after current function has returned?
>>
>> It means that the referenced object cannot change for the lifetime
>> of that reference.
>>
>> > Is it possible in Rust to create a hash that stores its' keys by
>> > borrowed reference (assuming that the hash does not outlive
>> > contained keys) and be assured that the keys will not get changed
>> > after having been added to the hash?
>>
>> That would be possible, but the hash would have to be parameterized by
>> the lifetime of the keys. What we typically do instead is to have the
>> hash own the keys.
>
>
> Not sure how this would prevent mutation of keys after they've been placed
> in the hash.  Could you please point me to an example?
>
> I agree that owning keys would simplify everything, but on more than one
> occasion I've had to index existing large objects to speed-up some lookup
> operation.  For example, let's say you need to de-dupe a vector of objects.
> In C++, I'd just create a hash_set of pointers to objects, but in Rust those
> would have to be borrowed references, right?  (assuming I don't want to
> resort to using raw pointers)
>
>> > - Can Rust actually guarantee that &mut are not aliased, - in the
>> > face of all indirection that may happen in a typical program?
>>
>> Yes. That is the job of the borrow checker, and the soundness of the
>> Rust type system depends on it. If you do not make use of managed data
>> (i.e., no `@`), this guarantee is static. Otherwise the guarantee is
>> enforced dynamically.
>>
>> The example program you gave is not supposed to execute without error;
>> the reason that it does is due to bugs. I am about to land (next day
>> or so) a branch fixing a number of such bugs. When I run that program
>> on my branch, I get a compilation failure. This is because, even
>> though you are using `@`, the compiler can clearly see that the
>> dynamic check would fail, and so it flags the error statically. If you
>> modify the program slightly you can evade this static check, but an
>> error should still occur dynamically. Currently it does not (even on
>> my branch), this is issue #5910.
>
>
> Would it be the same kind of error I am getting in Rust 0.6 if I use owned
> vector instead of a managed one?   This code fails to compile even if I'm
> borrowing distinct elements of z:
>
> fn add(x:&mut int, y:&mut int)
> {
>     *x = *x + *y;
> }
> pub fn main()
> {
>     let mut z = ~[1,2,3];
>     add(&mut z[0], &mut z[1]);
>     print(fmt!("%d\n", z[0]));
> }
>
> So this sort of code will not be possible?  (again, without raw pointers)
>
>
> Vadim

Immutable borrowed pointers guarantee that the object is immutable as
long as they exist (statically for Owned types, dynamically for @mut)
and &mut is unique. You can already use borrowed pointers as the keys
in maps/sets like this example with a set:

pub fn bfs<'r, N: Eq + IterBytes + Hash, M: Map<N, ~[N]>>(graph: &'r
M, start: &'r N, f: &fn(node: &'r N) -> bool) {
    let mut visited = HashSet::new();
    let mut q = Deque::new();
    q.add_back(start);

    while !q.is_empty() {
        let node = q.pop_front();
        visited.insert(node);

        for graph.find(node).unwrap().each |next| {
            if !visited.contains(&next) {
                f(next);
                q.add_back(next);
                visited.insert(next);
            }
        }
    }
}

@mut is basically an opt-out for most of the mutability/ownership
system and it won't prevent keys from being mutated externally. @ and
@mut are pretty much comparable to immutable/mutable objects in
Python, and Python doesn't allow mutable objects to be used as map
keys at all to avoid that edge case.
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to