If every type inside a tuple implements one of the following traits, then a tuple itself also implements it:
Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash
Is there a reason why the same is not true for traits like:
Zero, One
Neg, Not
Add, Sub, Div, Mul, Rem (and their *Assign counterparts)
BitAnd, BitOr, BitXor (and their *Assign counterparts)
Shl, Shr (and their *Assign counterparts)
Drop
I fail to see why we couldn't have:
let a: (X, Y, Z) = (x0, y0, z0);
let b: (X, Y, Z) = (x1, y1, z1);
assert_eq!(a + b, (x0 + x1, y0 + y1, z0 + z1));
and possibly for homogeneous tuples:
let a: (X, X, X) = (x0, x1, x2);
let n: X = x;
assert_eq!(a * n, (x0 * x, x1 * x, x2 * x));
I don't think it's a good idea to implement mathematical operators on tuples. You think it should be element-wise, but others may think e.g. multiplication should be like with mathematical vectors. There's special vectors implementing your operations for small tuple sizes in the vecmath and the nalgebra crates. You should be using them explicitly instead of relying on magic behavior of tuples.
Wrt Zero and One, yea, those should be there. As @ogeon notes, Drop is implicitly implemented for all types (just try it out, put an object that implements Drop in a tuple and drop the tuple).
Yeah, my bad for Drop@ogeon I didn't really think that one through.
Regarding the other traits, I hardly see that as magical. The tuple is not required to be homogeneous, the elements don't even have to be numbers; they could be strings, or vectors themselves, or a local type. I'm talking in a much more general sense.
Also, vector product is a very special case that can't apply to any type: the tuple must be homogeneous, elements must be numbers, and although I imagine one would use * in rust, since we can't define infix functions with arbitrary names like ^, the elements would have to implement more than just Mul which actually makes * unfit.
Additionally, I can't make a blanket implementation locally myself because of the orphan rule I believe, which means that operations can't be used at all on tuples. That's kind of a waste.
The only solutions are either to declare a new type or to explicitly repeat the operation on all the elements of both tuples. Not always very neat IMO.
Hmm, forwarding Zero to each tuple element is probably fine in general, but you can also get by with Default. I doubt there's a good interpretation for One though -- for instance, I would not expect a unit vector to be (1, 1).