You don't necessarily need variadic generics to enable tuples to be nominal types. Though you do need some changes to the generic type system. One possibility is:
struct Tuple_0_Int_1_Int<T/*, T0, T1*/>: Collection /*where T0: T, T1: T*/ { // Mangle name. Need covariant generics to enable constraint of T0 and T1. typealias Element = T typealias Index = Int typealias SubSequence = Slice<Tuple_0_Int_1_Int<T/*, T0, T1*/>> var _0_: T/*0*/ // Unique name. var _1_: T/*1*/ // Unique name. let startIndex: Int = 0 let endIndex: Int = 2 subscript(position: Int) -> T { switch position { case 0: return _0_ case 1: return _1_ default: fatalError("Index out of bounds (must be 0 or 1).") } } func index(after i: Int) -> Int { return i + 1 } } // Ideally: // 1. Extension on Tuple_0_Int_1_Int (SE-143). // 2. Collection extension rather than on every Tuple (SE-143 extension). func == <T>(lhs: Tuple_0_Int_1_Int<T>, rhs: Tuple_0_Int_1_Int<T>) -> Bool where T: Equatable { let size = lhs.count guard size == rhs.count else { return false } for i in 0 ..< size { guard lhs[i] == rhs[i] else { return false } } return true } The above is valid Swift 4, but I really want to be able to say: 1. `struct Tuple_0_Int_1_Int<T, T0, T1>: Collection where T0: T, T1: T`, i.e. covariant generics. 2. Ideally SE143+ also, so that I can extend Collection to implement Equatable, Hashable, etc. Note: 1. Tuples extend Collection, not MutableCollection. 2. T is the base type of T0 and T1. 3. A Collection of T is sufficient to write interesting generic algorithms; equals, etc. -- Howard. On 23 November 2017 at 11:50, David Sweeris via swift-evolution < swift-evolution@swift.org> wrote: > > On Nov 21, 2017, at 22:54, Douglas Gregor via swift-evolution < > swift-evolution@swift.org> wrote: > > On Nov 21, 2017, at 10:48 PM, David Hart <da...@hartbit.com> wrote: > > > > On 22 Nov 2017, at 07:41, Douglas Gregor via swift-evolution < > swift-evolution@swift.org> wrote: > > > > On Nov 21, 2017, at 10:37 PM, Chris Lattner <clatt...@nondot.org> wrote: > > On Nov 21, 2017, at 9:25 PM, Douglas Gregor <dgre...@apple.com> wrote: > > Or alternatively, one could decide to make the generics system *only and > forever* work on nominal types, and make the syntactic sugar just be sugar > for named types like Swift.Tuple, Function, and Optional. Either design > could work. > > > We don’t have a way to make it work for function types, though, because of > parameter-passing conventions. Well, assuming we don’t invent something > that allows: > > Function<Double, inout String> > > to exist in the type system. Tuple labels have a similar problem. > > > I’m totally aware of that and mentioned it upthread. > > > Eh, sorry I missed it. > > There are various encoding tricks that could make this work depending on > how you want to stretch the current generics system… > > > I think it’s straightforward and less ugly to make structural types allow > extensions and protocol conformances. > > > Can somebody explain to me what is less ugly about that? I would have > naturally thought that the language would be simpler as a whole if there > only existed nominal types and all structural types were just sugar over > them. > > > See Thorsten’s response with, e.g., > > Function<Double, InoutParam<String>, Param<Int>> > > which handles “inout” by adding wrappers around the parameter types (which > one would have to cope with in any user of Function), but still doesn’t > handle argument labels. To handle argument labels, we would need something > like strings as generic arguments. > > > Oh, good! A use case for “literals as generic parameters” *other* than > Vectors and Fixed-Size Arrays! > > - Dave Sweeris > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution > >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution