Is there a way to do this in Rust? Are recursive macros the answer? (Depth can be bounded if necessary.)
scaled_add(x,y,c) (or something like x.scaled_add(y,c) ) should return x + c*y if x,y are both of some type called F (which is a field). If instead x and y are Vec<F>, then do this elementwise and return a Vec<F>. If they are Vec<Vec<F>>, then return another Vec<Vec<F>>, etc.
Sorry, I didn't entirely follow the structure of your question. When I said that generic impls handle recursion, I meant recursion of the type Vec<Vec<...>>. You do not need, and therefore should not use, a macro for such cases; I am specifically recommending that you replace impl_scaled_add_for_vec with a generic impl.
For tuples of different lengths (which you did not mention in your original question), there is not any recursion involved, and you do have to use a macro to avoid repetition for different lengths. Someday Rust may have “variadic generics” to solve this, but it doesn’t today.
A straightforward way to write such a macro is:
macro_rules! impl_scaled_add_for_tuple {
($( $t:ident )*) => {
impl<$( $t: ScaledAdd, )*> ScaledAdd for ($( $t, )*) {
fn scaled_add(self, other: &Self, c: &F) -> Self {
...
}
}
}
}
impl_scaled_add_for_tuple!(A);
impl_scaled_add_for_tuple!(A B);
impl_scaled_add_for_tuple!(A B C);
impl_scaled_add_for_tuple!(A B C D);
impl_scaled_add_for_tuple!(A B C D E);
// ...
It’s possible to avoid the duplication in the macro calls, but I don't it's worth the added complexity.