`add_to` others `*_to` methods should be a trait and return the destination reference
Hello again dear maintainers
I find myself in the need of preallocated matrix operations, like add, mul, map and so. For this the _to methods taking a &mut out argument are great, however they are increasing the verbosity quite a lot. For two reasons:
- 2x more arguments (but we cannot avoid it)
- split expressions across many lines (and we can do something about it)
I suggest these functions could return the &mut out reference so we could chain these operations when needed.
The following example shows the concept on u32 operations
pub trait MulTo<Rhs, Rst> {
fn mul_to(&self, right: Rhs, result: Rst) -> Rst;
}
impl MulTo<u32, &mut u32> for u32 {
fn mul_to<'r>(&self, right: u32, result: &'r mut u32) -> &'r mut u32 {
*result = self * right;
result
}
}
fn main() {
let a = 2;
let b = 3;
let c = 4;
let mut tmp1 = 0;
let mut tmp2 = 0;
// and now without dynamic allocations (if it were matrices)
// result = a*b + c
let result = a.mul_to(b, &mut tmp1).add_to(c, &mut tmp2);
// result is a &mut u32 pointing into our tmp2 variable, so it can live as long as we do not need tmp2 again
}
On a diffferent topic, I suggest creating traits AddTo, SubTo, MulTo to generalize this to third-party types
I think perhaps this is better handled by the BLAS kernels, such as gemm. Would those work for your use case?
I do have some thoughts on a much more convenient kernel API though, which would really improve readability a lot. That's for another day though.
BLAS kernels could certainly be used in this example but this is not the point.
BLAS kernels do not return a reference to their out: &mut either, so they do not help reducing verbosity and increasing readability.
My point is simply: it would be more convenient to have *_to methods return their out reference so we can chain them in an expression