rust currently has support for vectors allocated on the task-local
heap (@[]s), but the support is essentially limited to creating
@-vector literals and indexing into them. There is currently no other
method of creating them. I've thought some about this, and I've
collected my thoughts:
* I want good, safe, interfaces for creating @-vectors. This is
tricky, since @-vectors basically need to be immutable. They can't be
resized if there might be more than one reference to them.
* A believe that a common case for building @-vectors will be wanting
to build up a vector that will then be immutable.
* A common thing in other languages is to allocate an array with a
fixed size that is either uninitialized or filled in with
zeros/null-pointers. This doesn't work in rust, because we don't have
null pointers. We could do this, but require a an initializing
element. This works, but is somewhat irritating and requires that the
elements be mutable.
* A common idiom in rust code that builds up ~-vectors is to start
with an empty vector and push elements onto the back. This seems like
a fairly satisfying way to build up vectors, but can't directly work
for @-vectors, which can't safely be updated in place. We could
accomplish this by creating an "avec" - a @-vector equivalent to dvec
that encapsulates the construction and can give back a @[] when done.
We probably will want to do this, but I feel like having it as the
only way of building @-vectors is somewhat unsatisfying, and it
doesn't fit in well with my plans for generic sequence code, discussed
below. So I think that "avec" should be one option for building
@-vectors, but not the only one.
* I don't want to have to duplicate basic sequence processing and
producing code for different sequences; I think things like split,
map, map2, filter, filter_map, concat, sep, unzip should all be
written once and work for @[], ~[], dvec, avec, list, and dlist. It
would also be super cool if the input and output sequences didn't
always need to be the same: we ought to be able to map from a list to
an @-vector.
* I think that if we want to accomplish this by parameterizing over
traits, we want some sort of static trait methods that we can call
without already having an object that implements that trait.
Otherwise, in order to generically create a new sequence, we need to
already have a sequence of that type.
* In order to create an interface that allows building up any of those
sequence types, it needs to not depend on using some other wrapper
type to manage the construction of it.
My proposed solution to this is to use an imperative "push" based
interface, but to use higher order functions to hide the vector under
construction. @-vectors will be constructed with a `construct`
function; `construct` takes as its argument a block that will build up
the vector; `construct` will create an empty sequence under the hood,
and call the block with a `push` closure that will push elements onto
the hidden vector. When the block returns, `construct` will return the
vector it has built up.
The type, for @-vectors, would be: fn construct<A>(build: fn(push:
fn(+A))) -> self;
An example of some code that could use it:
// Some code that could use that, then:
fn seq_range(uint lo, uint hi) -> @[uint] {
do construct() |push| {
for range(lo, hi) |i| {
push(i);
}
}
}
The critical feature of this interface is that the actual vector is
not exposed until after it has been constructed. The construct
function will be implemented unsafely, but it is a safe interface. (If
use of the vector needs to be interleaved with creation of it, then
you probably need to use `avec`)
One of the big advantages of this general interface is that it works
well for lots of different types; this would work for basically any
"sequence" type we have in rust. There are ways it can be extended,
too, like having construct take a size hint.
See https://gist.github.com/3101979, for some notes I wrote on my
ideas about static trait methods.
-sully
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev