-
-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Immutable collection operations #17
Comments
Yup I think the same! No bandwidth at the moment but feel free to open a PR |
@kirillsemyonkin this one is a bit more complicated, you can check here how they did the API in Immutable.JS: https://immutable-js.com/ Ideally you don't want to reproduce the JS API but stay as close as possible to the Rust API. Also you can clearly see in the API sample of this issue that we take an immutable in argument (&self) and we return a new owned value. That's the way to go because it's suppose to be immutable. I think it's possible that the reason why I did not make this "building" API is because it's not very optimal for the allocations. The user should probably make standard rust types (Vec, String, etc...) and then |
This is already a thing because of
Yeah, JS APIs are full of such things - they really like their array clones, and this really contradicts Rust's "blazingly fast" motto (I thought this was a community meme, but apparently they have it on their main page). I am also thinking of Also looking at Rust APIs for let mut vec = i_array.push(a);
vec.push(b); At that point, I personally would prefer following (which should already work): let mut vec = i_array.to_vec();
vec.push(a);
vec.push(b); |
One way to avoid a complete clone on every operation is to use collection types implemented with Hash Array Mapped Trie (HAMT), which is traditionally designed to return a new instance upon mutable operations. However, this may introduce significant bundle size increase and I haven't found any actively maintained Rust implementation for it. |
No I just forgot what I implemented lol. Maybe just documenting the use of to_vec() and such would be enough.
Yeah it's not idiomatic rust.... so probably it's best to take a different approach than re-allocating on every single operation.
@kirillsemyonkin I was thinking about this let mut builder = my_array.make_mut();
builder.push(x);
builder.push(y);
let new_array = builder.finish(); Maybe we can achieve this with a struct like this: pub struct ArrayBuilder<T>(Vec<T>);
impl Deref for ArrayBuilder {
// ...
}
impl DerefMut for ArrayBuilder {
// ...
}
impl<T> ArrayBuilder<T> {
pub fn finish(self) -> IArray<T> {
// ...
}
}
impl<T> IArray<T> {
pub fn make_mut(&mut self) -> ArrayBuilder<T> {
// ...
}
pub fn make_mut_with_capacity(&mut self) -> ArrayBuilder<T> {
// ...
}
} I'm not sure this is worth it at all because in the end it does look very much like the to_vec() solution except that you can pre-allocate differently with make_mut_with_capacity(). I like the idea of @futursolo but it looks like a lot of work. |
Just a little nitpick, but I would argue this is not builder pattern, and only
I'm not familiar with the structure. It is described as a structure used for maps. The Wikipedia page mentions |
these basic functions may be useful to include with the library
The text was updated successfully, but these errors were encountered: