Open mohammadfawaz opened 2 years ago
mutating an already existing value at given index is also a necessary function
mutating an already existing value at given index is also a necessary function
We should also make sure that Vec
and StorageVec
are in sync in terms of what methods they support.
Writing some notes since this was partially completed prior to assignment.
Note: (✅ if complete)
The contains
method is blocked by issue #3333, resolved by PR 3621, merge pending at time of writing.
Following up on the sort
method, it would be good to sort with multiple algorithms. However, in Rust, sort
uses a "Timsort inspired" algorithm while sort_unstable
uses a pattern defeating quicksort. The sort_by
method allows a user-defined function to be used when sorting, but at the time of writing this is not possible in Sway. Should we simply use the sort
and sort_unstable
algorithm or should we extend the API to implement other sorting methods?
Assuming we implement multiple sorting methods, which of the following would be best? Neither has overlap with the Rust Vec
API.
Option 1:
impl<T> Vec<T> {
// in rust api
fn sort(ref mut self) {}
fn sort_unstable(ref mut self) {}
// beyond rust api
fn bubblesort(ref mut self) {}
fn insertionsort(ref mut self) {}
}
Option 2:
enum SortingAlgorithm {
Bubblesort,
Insertionsort,
}
impl<T> Vec<T> {
// in rust api
fn sort(ref mut self) {}
fn sort_unstable(ref mut self) {}
// beyond rust api
fn sort_with(ref mut self, algorithm: SortingAlgorithm {
match algorithm {
SortingAlgorithm::Bubblesort => {}
SortingAlgorithm::Insertionsort => {}
};
}
}
Let start by following Rust for now - this may be all we need in the foreseeable future. (So sort
and sort_unstable
). Eventually we'll have the ability to pass closures to functions we'll be able to implement sort_by
.
Oh and you can't use recursion yet so keep that in mind when implementing quick sort.
In the storage vector, what would be desirable behavior for split_off
and split_at
?
In the memory vector, split_off(&mut self, at: u64) -> Vec<T>
creates a new memory vector starting at the at
argument (inclusive) to return then resizes the original vector down to the at
argument (exclusive). However, in the storage vector, returning a new storage vector does not seem possible. One possible way to do this is to create a new memory vector starting at the at
argument to return then clear all storage vector elements from self.len - at
to self.len - 1
, but this seems clunky.
In the memory vector, split_at(&self, mid: u64) -> (Vec<T>, Vec<T>)
does not mutate the original vector, but returning two storage vectors does not seem possible. As with the above, we could return memory vectors, but this still seems clunky.
Thoughts on the proposed implementations? We can also await the type conversion between StorageVec
and Vec
mentioned in #2439 (not a guaranteed change, but this could serve as motivation to push them), or we could simply not implement them and accept API differences between the memory and storage vectors.
Also, the append(&mut self, other: &mut Vec<T>)
method, according to the Rust implementation, clears the other
vector when it is appended to self
.
This is marginal to implement in memory vectors despite differences in Sway's and Rust's memory models, but in storage vectors, this would require N
reads, N
writes, and N
clears where N
is the length of the other
vector. Is this the behavior we want for the storage vector as well?
I think for append
it's okay to deviate a bit and avoid unnecessary clearing, especially in StorageVec
.
If split_off
and split_at
seems difficult and expensive for StorageVec
, we can consider skipping them honestly. It's also reasonable to implement #2439 before we attempt these, if that makes more sense.
Can this be closed now that the PRs in https://github.com/FuelLabs/sway/pull/3935#issuecomment-1442578506 have been merged?
Can this be closed now that the PRs in #3935 (comment) have been merged?
If all features are implemented then sure otherwise I would make a list of the ones that are not implemented and potentially create individual issues for them so that this can be closed.
An example of a good method to add would be
contains()
. There are probably plenty of other methods that we can add from https://doc.rust-lang.org/stable/std/vec/struct.Vec.html