These are chat archives for rust-lang/rust

14th
May 2019
Omer Katz
@thedrow
May 14 12:56
What's the best way to call foo() N times and append the result into a Vec? Is there a way to do so without a for loop?
Michal 'vorner' Vaner
@vorner
May 14 13:02
vec.extend(iter::repeat(()).take(n).map(|_| foo()))
Ingvar Stepanyan
@RReverser
May 14 13:04
@thedrow @vorner better yet: vec.extend(iter::repeat_with(foo).take(n))
Omer Katz
@thedrow
May 14 13:05
I don't have an existing vec. Will collect be enough?
Ingvar Stepanyan
@RReverser
May 14 13:05
oh, you said "append the result into a vec" which seemed to imply you already have a vec
Omer Katz
@thedrow
May 14 13:05
Because I did at first
Ingvar Stepanyan
@RReverser
May 14 13:05
Yeah then use collect
Omer Katz
@thedrow
May 14 13:05
Now I have the following version:
(0..n).map(|_| {
                UUID {
                    handle: Uuid::new_v4(),
                }
            }).collect()
Ingvar Stepanyan
@RReverser
May 14 13:06
iter::repeat_with(|| UUID {
  handle: Uuid::new_v4()
}).take(n).collect()
slightly cleaner IMO
Omer Katz
@thedrow
May 14 13:07
I agree. Thanks
Robyn Speer
@rspeer
May 14 21:12
I'm trying to refactor some repetitive code into a separate function, and the references I have don't seem to allow the same operations I'd be able to do if I kept the code inline. Here's my function:
fn update_rows(
    mat: &mut Array2<f32>,
    grad: &mut Array1<f32>,
    this_idx: usize,
    other_idx: usize,
    learning_rate: f32,
) {
    let dotprod: f32 = mat
        .row(this_idx)
        .dot(&mat.row(other_idx));
    let badness: f32 = 1. - sigmoid(dotprod);
    let grad_update: Array1<f32> =
        &mat.row(other_idx) * badness * learning_rate;
    grad += &grad_update;
}
(there would be more beyond that, but here's where I encounter the error)
The error I get is:
error[E0368]: binary assignment operation `+=` cannot be applied to type `&mut ndarray::ArrayBase<ndarray::OwnedRepr<f32>, ndarray::dimension::dim::Dim<[usize; 1]>>`
   --> src/lib.rs:172:5
    |
172 |     grad += &grad_update;
    |     ----^^^^^^^^^^^^^^^^
    |     |
    |     cannot use `+=` on type `&mut ndarray::ArrayBase<ndarray::OwnedRepr<f32>, ndarray::dimension::dim::Dim<[usize; 1]>>`
    |
    = note: an implementation of `std::ops::AddAssign` might be missing for `&mut ndarray::ArrayBase<ndarray::OwnedRepr<f32>, ndarray::dimension::dim::Dim<[usize; 1]>>`
and what's odd is that I could do that operation to grad if I were still in the function where grad was declared, with let mut grad: Array1<f32> = Array::zeros((n_dim,));
Siddhant Sanyam
@siddhant3s
May 14 21:15
It might be that module had the implementation of AddAssign imported while this module doesn't.
Robyn Speer
@rspeer
May 14 21:15
Same module.
This is code that I just cut from an existing function and put into this function, because I need to do it twice.
at different times, so it's not just a loop. It's a straightforward example of code that should be factored out into a separate function. But I lose the ability to do += when I do that.
If I'm understanding it correctly -- referring to the array type as its shorter name, Array2<f32> -- then I can use += on a variable that's declared as mut Array2<f32>, but not a parameter that's declared as &mut Array2<f32>. But it has to be a reference for me to pass it to this function.
Denis Lisov
@tanriol
May 14 21:19
*grad += &grad_update;
Siddhant Sanyam
@siddhant3s
May 14 21:19
Oh I see, may be you should dereference it then?
*grad += grad_update
Robyn Speer
@rspeer
May 14 21:20
Aha. I didn't know *grad was something you could do on the left-hand side.
(also I meant Array1<f32> but it didn't matter)
Siddhant Sanyam
@siddhant3s
May 14 21:58
Holy shit, the --release makes such a difference. On this particular use case.... it was 50x faster in speed and 3x smaller in size.
Ichoran
@Ichoran
May 14 22:19
@rspeer - In your case I think you want to pass by mutable reference and dereference inside. But it is also possible to move ownership into the function and back out again. For example:
struct Foo {
    i: u32
}

fn add(foo: Foo, j: u32) -> Foo {
    let mut foo = foo;
    foo.i += j;
    foo
}

fn main() {
    let foo = Foo { i: 0 };
    let foo = add(foo, 2);
    println!("{}", foo.i);
}
Ichoran
@Ichoran
May 14 22:32
(You can move and make mutable in one go with add(mut foo: Foo, ....)