Idea: TryIndexAs/TryIndexMutAs for generalization over tuples


Nowadays it’s really really hard if not possible to generalize over tuple type. After reading Nascent Idea: allow `.0`, `.1`, etc on arrays, I’ve come up with this idea:

Imagine there’re traits:

trait TryIndexAs<T> {
     fn try_index_as(&self, index: usize) -> Option<&T>;

trait TryIndexMutAs<T> {
     fn try_index_mut_as(&mut self, index: usize) -> Option<&mut T>;

And the compiler somehow managed to implement them for all the tuple types, when index and T corresponding to a position in a tuple, it returns Some, otherwise it will just return None:

impl<A> TryIndexAs<A> for (A,) {

impl<A> TryIndexAs<A> for (A,A) {

impl<A,B> TryIndexAs<A> for (A,B) {

impl<A,B> TryIndexAs<B> for (A,B) {

So one will be able to use impl TryIndexAs<A> + TryIndexAs<B> to generalize over all tuples consisting of types A and B and other types.

Is this a good idea?


This feels like it should be part of a discussion on variadic generics in general, since it’s not at all clear to me whether this is possible today but would be immediately made obsolete by proper variadic generics, or is blocked today on variadic generics, or some other more complicated relationship.

Plus, it’s kind of hard to meaningfully evaluate a proposal when zero use cases are given for it :slight_smile: I simply don’t know what you’d want to do with this.


These impls you conflict and will not compile. So this doesn’t work.


I know, i didn’t mean to put these literally at all, or it will be a library…


It wouldn’t work in a library either because of the coherence rules.

Anyway, I also feel generalization over tuples is much better served (in the “more general solution” sense) by proper variadic generics than any partial workaround.

Secondly, I don’t really why what is being proposed here is useful. If you want to abstract over types, you still have to enumerate them explicitly in the trait bounds. It also introduces the possibility for runtime overhead (you are basically asking the compiler to generate downcasting boilerplate for you), which sounds undesirable (even though I’m almost sure it will be optimized away).

I think we should just wait for proper variadic generics instead.


@H2CO3 The problem is: It’s not clear to me that we’re moving towards proper variadic generics in the near future or even at all. Even if we do, can variadic generics simply solve ALL or ALMOST ALL the problems for tuples the way RFC2000 solves problems for array? That is not necessarily the case.


If you feel like that, I think you should instead try to revive efforts and discussion around variadic generics. They might not be easy to get, but a well-thought, major feature is strictly superior to the addition of eventually many, small, fragmented features for solving specialized problems.

RFC2000 is const generics. If by “solves all problems for arrays” you mean “you can now abstract over an array of generic/arbitrary size”, then yes, variadic generics would solve the same problems for tuples — as well as other important ones, including the ability to abstract over functions with a different number of arguments.


thanks, do you have any reference to this? The later cases, e.g. abstracting over different number of arguments is natural for variadic generics. But it doesn’t have to be tuple-based, i think. RFC1935 comes in a tuple-based approach, but i still think it’s not that clear that there’s such tight connection between tuple and variadic generics.


Sorry, I don’t have any particular references apart from having used variadic generics in other languages and it being one of the main points of that feature. Tuples are a heterogeneous, static ordered sequence of values, and could be easily constructed/destructured generically just like function arguments could be manipulated. It’s kind of obvious to me so I don’t really understand your doubts as to why they wouldn’t work especially with tuples. Not sure about the current actual state of any related RFCs if any, but variadic generics could certainly and naturally be designed to support both tuples and other use cases. (And I don’t think one would have to make function argument lists into tuples in order to make variadics work for tuples.)