The Generics Manifesto and single-element tuples

Thanks again, I really appreciate you taking the time to answer these questions.

I mentioned that bug as an example because of the conversation (between @mattrips and @beccadax) in its comments, eg:

I'm afraid that I'd be putting a band-aid on a small symptom of a larger bug. The code that folds (T) is doing something that is fundamentally illegal.
It is creating a single-element tuple, but there is no such thing as a single-element tuple. The documentation states that, "All tuple types contain two or more types, except for Void which is a type alias for the empty tuple type, ()."

Internally, Swift actually does use single-element tuples purposefully in some cases (mainly for single labeled arguments). But we know they sneak through sometimes when they shouldn't. The set of refactorings needed to fix it properly is too big to do immediately, but several of us are gearing up to wage war on the root causes of these problems.
So apply your band-aid and bide your time. Honestly, if it actually fixes a single-element tuple instead of just limiting the damage, it's better than the tuple band-aid I wrote a couple weeks ago.

And also because of the content of the reporter's (also assignee's) related post here.


You're right, but I'd prefer if the implicit splat wasn't there (and thus that the 1-tuple's type was separate from its element), since it would allow me to eg write extensions on all tuple types for which all (0 or more) elements satisfies some constraint etc. But as shown above, the current special casing of 1-tuples makes that complicated or impossible in the general case (the current special casing results in the need for further special casing). It would be interesting to hear if @Torust has any thoughts about this feedback.

I see your point, but again, I still don't like the special casing of 1-tuples (having an implicit tuple splat), even here, because it's trading consistency (and the power/simplicity it implies) for mild convenience in a specific case (by introducing an inconsistency and the trouble/complexity it implies).

I'm not sure if it's interesting or not to contemplate the behavior of the following depending on if 1-tuples existed as separate types from their element's type or not:

func foo<...T>(_ types: T.Type...) {
    print(scan(types))
    // Or would it be:
    // print(scan(T...))
    // ?
}

I'd be happy to come to the conclusion that my worries and/or preferences are founded on false premises, but I'm afraid I seem to need a lot of explanation in order to arrive at that conclusion.
: )

1 Like