Parameterized extensions of nominal types are something we would like to add at some point. The syntax for tuple conformances can be introduced without the full feature though, the only overlap is parser support.
Good question.
There are a couple of reasons, maybe not entirely convincing. Tuple elements can have labels, whereas type packs cannot carry labels (as currently proposed, at least).
Another reason is that tuples have special behavior in the type checker with implicit conversions between tuple types where element types convert, for example. Of course, you can imagine a language where Tuple is a type in the standard library that still has special type checker behavior (just like Optional does today, for example).
Tuples are also special in other ways, for example an obscure difference between a tuple and a generic struct is that closures can be stored in a tuple at different abstraction levels (calling conventions) whereas a closure stored in a generic struct (struct G<T> { var t: T }
) must be wrapped in a thunk that passes all parameters and results indirectly. But again, Optional
has the same behavior where SILGen knows how to apply re-abstraction thunks as needed to the optional payload.
Perhaps if we were starting from scratch, we could do away with tuples as a primitive type entirely, but for now having tuples be their own thing still continues to make sense.
There's no real reason this cannot be supported eventually. My thinking is that adding members to arbitrary tuple types is potentially confusing and merits further discussion, and initially we would only allow this exact syntax
extension <T...> (T...): P where T: P {}
that is,
- the extension must define a conformance of the tuple type to P
- the conformance must be conditional on each element conforming to P
- no other requirements are permitted
However, we could relax these restrictions over time if good use-cases are proposed, and then something like
extension (Int, Bool) {}
would desugar to
extension <T...> (T...) where (T...) == (Int, Bool) {}
You could even imagine something like
extension <T..., U> (T...) where (T...) == (Int, U, Bool), U: Equatable {}
with the shorter equivalent form
extension (Int, some Equatable, Bool) {}
But all that extra sugar could probably go in a stand-alone pitch/proposal.