Sami Nopanen wrote:
Hi,

Some random questions based on playing around with Rust for a few weeks.

1. Do mutable variant types allocated in stack always occupy a fixed space (the size of the largest possibly value) ?

Yes.

2. How to allocate a mutable managed vector dynamically?
I can create an owned vector with: let a = vec::from_elem(..);
I can create a managed vector with: let a = at_vec::from_elem(..);

You cannot. Because the elements of a managed vector are stored inline without indirection, and managed vectors are inherently shared, they cannot change length after they are created. Think of a managed vector like a Java array, which has the same properties.

If you want a mutable vector, you must place an owned vector into a managed box. At the moment, this is most conveniently done using the `DVec` wrapper (this is what it exists for). That is, a type like `@DVec<T>` is basically the equivalent of Java's `ArrayList<T>`.

In the future, we currently plan to build in better support for managed, mutable data using a plan, so it is likely that `@DVec<T>` will be removed in favor of something like `@mut ~[T]`.

3. Can you return stack allocated literal vectors (either using the create directly in calling stack semantic or as a copied value type)?
I tried:
fn newInStack() -> [int] { [1, 2] }
But was hit with a compile error.

You can only return types with a fixed size, and you cannot return pointers into your own stack frame. The return type you gave here (`[int]`) is not in fact a valid Rust type. Arrays come in two varieties: pointers, like `~[int]`, `@[int]`, or `&[int]`, and fixed-length, like `[int * 2]`. That function might best be written using a fixed-length vector (`[int * 2]`), presuming of course you know how long the result will be. This would be legal because the caller would know how much memory to allocate in order to store the array on their stack, and then the callee will write directly into the caller's stack frame. 4. Can you control where a result gets built from the calling side? Making several copies of a simple
constructor function to be able to allocate things in different places seems a bit silly.
fn newInStack() -> Foo { Foo(1,2) }
fn newOwned() -> ~Foo { ~Foo(1,2) }
fn newManaged() -> @Foo { @Foo(1,2) }

Yes, that would be silly, but you don't have to do it. Just make the one version that returns by value:

fn newFoo() -> Foo { Foo(1, 2) }

and then in the caller's side you can write `@newFoo()` or `~newFoo()` as desired. This doesn't work with vector returns, though. If you want to write a function that results in a vector of unknown length it's easiest to just return `~[int]`, though it is possible to use generic builder types to return either `@[int]` or `~[int]` depending on what the user wants.

I especially was wondering about this in the context of 'vec' and 'at_vec' and trying (and failing) to create a mutable managed array; and left wondering if I'd need to create a new module 'at_mut_vec'. (And somewhere in the back of my head wondering, if all these modules would really be needed or if this is an indication of a
problem with expressiveness of the language in such cases).

There is something of a balancing act here. In principle there are many, many ways that one could write generic functions (generic over @ vs ~, generic over mutability, etc) but we've tried to keep that limited in order to best manage complexity. There are ways to write functions and types that maximize reusability: • Use borrowed pointers whenever possible so that you can accept inputs from anywhere (stack, `@`, `~`).
• Return value types (like `Foo`) instead of a pointer type (like `@Foo).
• If you can't use `&`, `~` is somewhat more general than `@`, because a `~` value can always be placed into a managed box. • Use inherited mutability rather than declaring mutability at the field level to allow for freezing.

We are still tuning some of these aspects—particularly mutability—and we plan on removing some of the "choices" that are available today, at least once we're certain what the best choices are.


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

Reply via email to