-
Notifications
You must be signed in to change notification settings - Fork 4
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
Allow to collect into savvy's types #125
Comments
Thanks, good point. I think you can use |
I am not sure I follow... How would you use #[savvy]
fn times_two(x: IntegerSexp) -> savvy::Result<savvy::Sexp> {
let out: Vec<i32> = x.iter().map(|v| v * 2).collect();
out.try_into()
} |
I meant something like this. (Sorry, it was #[savvy]
fn times_two(x: IntegerSexp) -> savvy::Result<savvy::Sexp> {
let mut out = unsafe { OwnedIntegerSexp::new_without_init(x.len())? };
let out_s = out.as_mut_slice();
for (i, v) in x.iter().enumerate() {
out_s[i] = v * 2;
}
out.into()
} |
oh I didn't know it was possible. Thanks. |
Current progress: I found implementing
Ignoring an error can be an option, but I feel it's not good to encourage it to the users. I'll implement |
I'm giving up this for now, at least until I find the right interface for this. Thinking the comment above again, I found Next, I tried to implement psuedo implementationimpl TryFrom<dyn IntoIterator<Item = i32>> for OwnedIntegerSexp {
type Error = crate::error::Error;
fn try_from(value: dyn IntoIterator<Item = i32>) -> crate::error::Result<Self> {
let iter = iter.into_iter();
match iter.size_hint() {
(_, Some(upper)) => {
let mut out = unsafe { OwnedIntegerSexp::new_without_init(upper)? };
let mut actual_len = 0;
for (i, v) in iter.enumerate() {
out[i] = v;
actual_len = i;
}
if actual_len != upper {
unsafe {
savvy_ffi::SETLENGTH(out.inner, actual_len as _);
}
}
Ok(out)
}
(_, None) => {
let v: Vec<i32> = iter.collect();
v.try_into()
}
}
}
} Btw, one correction to my example code above. I forgot I implemented it, but #[savvy]
fn times_two(x: IntegerSexp) -> savvy::Result<savvy::Sexp> {
let mut out = unsafe { OwnedIntegerSexp::new_without_init(x.len())? };
for (i, v) in x.iter().enumerate() {
out[i] = v * 2;
}
out.into()
} |
Thanks. I managed to use your solution like this, avoiding the bound check from #[savvy]
fn times_two(x: savvy::IntegerSexp) -> savvy::Result<savvy::Sexp> {
let mut out = unsafe { savvy::OwnedIntegerSexp::new_without_init(x.len())? };
for (x_, out_) in x.iter().zip(out.as_mut_slice().iter_mut()) {
*out_ = *x_ * 2;
}
out.into()
}
|
I was taking a look at arrow2 crate and it seems that for some reason the author also chose to create methods instead of implementing |
Thanks for the attempt. https://yutannihilation.github.io/savvy/guide/08_atomic_types.html
Oh, looking at how arrow does is a nice idea! Good to know, thanks. But, it seems they implement https://docs.rs/arrow/latest/arrow/array/struct.PrimitiveArray.html#method.from_iter |
I did notice that, but I liked how the author made its API. I liked it way more than arrow. I think arrow2 is being continued inside polars, while the original was archived. |
If you are curious, you can read the context related to polars and arrow2 here. |
Okay, I think https://docs.rs/arrow/latest/arrow/array/struct.FixedSizeBinaryArray.html#method.try_from_iter |
my initial idea was something like from_trusted_len_iter, since savvy's constructors are all based on a fixed length. But TIL that |
In my understanding, |
Actually if I just have a I agree with you though that most users will look for those unknown length cases. Probably your future |
Oh, the case in your mind has an already-allocated Lines 186 to 194 in bee3c73
|
I think half of the problems are solved. Let's close this for now and revisit when |
I was reading your guide about creating R objects and I think the most efficient way, avoiding bound checks every time that
set_elt
is called, would probably be allowing to collect into those types. Would it be possible?Another possibility would be to create an unsafe
set_elt
that lets the user control the bound checks... But I really like more the first idea.The text was updated successfully, but these errors were encountered: