CollectionType on uniform tuples [forked off Contiguous Variables]


(Félix Cloutier) #1

Hi all,

Since the original fixed-size array thread is somewhat stalling, I forked off the subscript part into this: Treat uniform tuples as collections <https://github.com/zneak/swift-evolution/blob/uniform-tuples/proposals/00nn-collectiontype-for-tuples.md>

Félix

Treat uniform tuples as collections

Proposal: SE-NNNN <https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md>
Author(s): Swift Developer <https://github.com/swiftdev>
Status: Awaiting review
Review manager: TBD

Introduction

This proposal aims at adding collection operations to uniform tuples: tuples in which every element has the same type, and no element has a label.

Swift-evolution thread: Proposal: Contiguous Variables (A.K.A. Fixed Sized Array Type) <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160208/009520.html>
Motivation

Fixed-size arrays in C structures are imported as tuples. This means that on the Swift side, developers therefore lose the ability to use even the most basic collection type operations on them, like subscripts. When collection operations are needed, it is usually necessary to transform the tuple into a full-fledged Swift Array using unsafe pointers.

Proposed solution

This proposal suggests adding CollectionType conformance to uniform tuples.

Detailed design

Any tuple of more than one element, in which every element has the same type, is eligible for CollectionType conformance. CollectionType elements are generated as such:

Generator: opaque. Possibly based off UnsafeBufferPointers, possibly the same for all uniform tuples (to a generic parameter).
Index: Int.
SubSequence: Array, since tuples are value types and cannot be shared without being copied wholesale anyway, and the dynamic nature of SubSequence means that it usually is impossible to simply return a smaller tuple (whose size has to be known at compile-time).
count: the number of elements in the tuple.
first: tuple.0
isEmpty: false
subscript(_: Self.Index): single element at given index. Bounds-checked.
subscript(_: Range<Self.Index>): sub-sequence Array. Bounds-checked.
startIndex: 0.
endIndex: count.
It is worth noting that uniform tuples do not lose static field access. This avoids needlessly breaking existing code and allows developers to bypass bounds-checking for indices known to be safe.

Impact on existing code

No impact on existing code; the feature is purely additive.

Alternatives considered

A simpler syntax to declare uniform tuples from Swift, like (Int x 4), was found to be contentious. This proposal forks off the original for incremental implementation of the feature.

The original proposal only called for a subscript on uniform tuples. Adding full CollectionType support seemed simple enough and useful enough to suggest it.

It was suggested that uniform tuples should lose their static field access syntax to ensure that there is Just One Way to access tuple elements. However, this could have surprising side effects on existing code and wouldn't be possible with generic code.


(Joe Groff) #2

Making tuples or other structural types able to conform to protocols has some implementation challenges—after all, we'd also like some tuples to ultimately be Equatable/Hashable/Comparable as well. Making homogeneous tuples subscriptable is easy progress that moves us in the right direction; we can consider protocol conformances later.

-Joe

···

On Feb 11, 2016, at 9:12 AM, Félix Cloutier via swift-evolution <swift-evolution@swift.org> wrote:

Hi all,

Since the original fixed-size array thread is somewhat stalling, I forked off the subscript part into this: Treat uniform tuples as collections <https://github.com/zneak/swift-evolution/blob/uniform-tuples/proposals/00nn-collectiontype-for-tuples.md>

Félix

Treat uniform tuples as collections

Proposal: SE-NNNN <https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md>
Author(s): Swift Developer <https://github.com/swiftdev>
Status: Awaiting review
Review manager: TBD

Introduction

This proposal aims at adding collection operations to uniform tuples: tuples in which every element has the same type, and no element has a label.

Swift-evolution thread: Proposal: Contiguous Variables (A.K.A. Fixed Sized Array Type) <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160208/009520.html>
Motivation

Fixed-size arrays in C structures are imported as tuples. This means that on the Swift side, developers therefore lose the ability to use even the most basic collection type operations on them, like subscripts. When collection operations are needed, it is usually necessary to transform the tuple into a full-fledged Swift Array using unsafe pointers.

Proposed solution

This proposal suggests adding CollectionType conformance to uniform tuples.

Detailed design

Any tuple of more than one element, in which every element has the same type, is eligible for CollectionType conformance. CollectionType elements are generated as such:

Generator: opaque. Possibly based off UnsafeBufferPointers, possibly the same for all uniform tuples (to a generic parameter).
Index: Int.
SubSequence: Array, since tuples are value types and cannot be shared without being copied wholesale anyway, and the dynamic nature of SubSequence means that it usually is impossible to simply return a smaller tuple (whose size has to be known at compile-time).
count: the number of elements in the tuple.
first: tuple.0
isEmpty: false
subscript(_: Self.Index): single element at given index. Bounds-checked.
subscript(_: Range<Self.Index>): sub-sequence Array. Bounds-checked.
startIndex: 0.
endIndex: count.
It is worth noting that uniform tuples do not lose static field access. This avoids needlessly breaking existing code and allows developers to bypass bounds-checking for indices known to be safe.

Impact on existing code

No impact on existing code; the feature is purely additive.

Alternatives considered

A simpler syntax to declare uniform tuples from Swift, like (Int x 4), was found to be contentious. This proposal forks off the original for incremental implementation of the feature.

The original proposal only called for a subscript on uniform tuples. Adding full CollectionType support seemed simple enough and useful enough to suggest it.

It was suggested that uniform tuples should lose their static field access syntax to ensure that there is Just One Way to access tuple elements. However, this could have surprising side effects on existing code and wouldn't be possible with generic code.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Douglas Gregor) #3

Hi all,

Since the original fixed-size array thread is somewhat stalling, I forked off the subscript part into this: Treat uniform tuples as collections <https://github.com/zneak/swift-evolution/blob/uniform-tuples/proposals/00nn-collectiontype-for-tuples.md>

This specific proposal is a non-starter for me, because it lands squarely in the "death valley" of being extremely invasive on the implementation while providing only a small amount of relative value.

Swift’s implementation—from semantic analysis through SIL and the runtime—assume that the only types that can conform to protocols are so-called “nominal” types, which have names that are meaningful in the runtime. Swift’s nominal types are structs, classes, enums, and protocols. Compound types such as functions, tuples, and protocol compositions, as well as aliases of types (typealiases), are not nominal. It is absolutely possible to generalize Swift’s implementation to deal with non-nominal types that conform to protocols, but it is going to be a significant amount of work across the compiler and runtime. That work is way out of scope of Swift 3, and needs to be justified by major improvements to the language.

Making some class of tuples conform to CollectionType isn’t a big enough justification. Giving me the ability, as a user, to extend tuple types to make them conform to a particular protocol myself might be big enough. For example, if I combined that with some kind of variadic generics, parameterized extensions, and conditional conformances, I could express “make any tuple of Hashable types Hashable”:

extension<T... where T : Hashable...> (T...) : Hashable {
  var hashValue: Int {
    return combineHash(self.hashValue...)
  }
}

I’m appropriating the syntax of C++11 variadic templates for this example, but essentially ’T’ is acting as a bunch of separate type parameters that can be expanded into separate type arguments with “T…”. While the syntax doesn’t matter so much, there is significant user-level impact here: one could use tuples as keys of a Dictionary or elements of a Set, make tuples conform to protocols for serialization, and so on.

  - Doug

···

On Feb 11, 2016, at 9:12 AM, Félix Cloutier via swift-evolution <swift-evolution@swift.org> wrote:

Félix

Treat uniform tuples as collections

Proposal: SE-NNNN <https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md>
Author(s): Swift Developer <https://github.com/swiftdev>
Status: Awaiting review
Review manager: TBD

Introduction

This proposal aims at adding collection operations to uniform tuples: tuples in which every element has the same type, and no element has a label.

Swift-evolution thread: Proposal: Contiguous Variables (A.K.A. Fixed Sized Array Type) <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160208/009520.html>
Motivation

Fixed-size arrays in C structures are imported as tuples. This means that on the Swift side, developers therefore lose the ability to use even the most basic collection type operations on them, like subscripts. When collection operations are needed, it is usually necessary to transform the tuple into a full-fledged Swift Array using unsafe pointers.

Proposed solution

This proposal suggests adding CollectionType conformance to uniform tuples.

Detailed design

Any tuple of more than one element, in which every element has the same type, is eligible for CollectionType conformance. CollectionType elements are generated as such:

Generator: opaque. Possibly based off UnsafeBufferPointers, possibly the same for all uniform tuples (to a generic parameter).
Index: Int.
SubSequence: Array, since tuples are value types and cannot be shared without being copied wholesale anyway, and the dynamic nature of SubSequence means that it usually is impossible to simply return a smaller tuple (whose size has to be known at compile-time).
count: the number of elements in the tuple.
first: tuple.0
isEmpty: false
subscript(_: Self.Index): single element at given index. Bounds-checked.
subscript(_: Range<Self.Index>): sub-sequence Array. Bounds-checked.
startIndex: 0.
endIndex: count.
It is worth noting that uniform tuples do not lose static field access. This avoids needlessly breaking existing code and allows developers to bypass bounds-checking for indices known to be safe.

Impact on existing code

No impact on existing code; the feature is purely additive.

Alternatives considered

A simpler syntax to declare uniform tuples from Swift, like (Int x 4), was found to be contentious. This proposal forks off the original for incremental implementation of the feature.

The original proposal only called for a subscript on uniform tuples. Adding full CollectionType support seemed simple enough and useful enough to suggest it.

It was suggested that uniform tuples should lose their static field access syntax to ensure that there is Just One Way to access tuple elements. However, this could have surprising side effects on existing code and wouldn't be possible with generic code.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Chris Lattner) #4

I agree with Doug on this. I still think the right approach is to:

1) add a subscript on tuples with a consistent element kind.
2) add some type sugar for defining these types
3) consider a convenient form for defining an initializer on these.

To me, that is the order of priority. Just getting #1 and #2 would seriously move the needle on making C arrays work better, with very little implementation complexity. #3 would be nice, but seems less important.

-Chris

···

On Feb 11, 2016, at 10:59 AM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

On Feb 11, 2016, at 9:12 AM, Félix Cloutier via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Hi all,

Since the original fixed-size array thread is somewhat stalling, I forked off the subscript part into this: Treat uniform tuples as collections <https://github.com/zneak/swift-evolution/blob/uniform-tuples/proposals/00nn-collectiontype-for-tuples.md>

This specific proposal is a non-starter for me, because it lands squarely in the "death valley" of being extremely invasive on the implementation while providing only a small amount of relative value.


(Matthew Johnson) #5

Hi all,

Since the original fixed-size array thread is somewhat stalling, I forked off the subscript part into this: Treat uniform tuples as collections <https://github.com/zneak/swift-evolution/blob/uniform-tuples/proposals/00nn-collectiontype-for-tuples.md>

This specific proposal is a non-starter for me, because it lands squarely in the "death valley" of being extremely invasive on the implementation while providing only a small amount of relative value.

Swift’s implementation—from semantic analysis through SIL and the runtime—assume that the only types that can conform to protocols are so-called “nominal” types, which have names that are meaningful in the runtime. Swift’s nominal types are structs, classes, enums, and protocols. Compound types such as functions, tuples, and protocol compositions, as well as aliases of types (typealiases), are not nominal. It is absolutely possible to generalize Swift’s implementation to deal with non-nominal types that conform to protocols, but it is going to be a significant amount of work across the compiler and runtime. That work is way out of scope of Swift 3, and needs to be justified by major improvements to the language.

Making some class of tuples conform to CollectionType isn’t a big enough justification. Giving me the ability, as a user, to extend tuple types to make them conform to a particular protocol myself might be big enough. For example, if I combined that with some kind of variadic generics, parameterized extensions, and conditional conformances, I could express “make any tuple of Hashable types Hashable”:

extension<T... where T : Hashable...> (T...) : Hashable {
  var hashValue: Int {
    return combineHash(self.hashValue...)
  }
}

I’m appropriating the syntax of C++11 variadic templates for this example, but essentially ’T’ is acting as a bunch of separate type parameters that can be expanded into separate type arguments with “T…”. While the syntax doesn’t matter so much, there is significant user-level impact here: one could use tuples as keys of a Dictionary or elements of a Set, make tuples conform to protocols for serialization, and so on.

+1 to eventually having this kind of flexibility. But I agree that baking special cases into the language itself is not necessary. It can wait until we can have the general capability.

···

On Feb 11, 2016, at 12:59 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

On Feb 11, 2016, at 9:12 AM, Félix Cloutier via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

  - Doug

Félix

Treat uniform tuples as collections

Proposal: SE-NNNN <https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md>
Author(s): Swift Developer <https://github.com/swiftdev>
Status: Awaiting review
Review manager: TBD

Introduction

This proposal aims at adding collection operations to uniform tuples: tuples in which every element has the same type, and no element has a label.

Swift-evolution thread: Proposal: Contiguous Variables (A.K.A. Fixed Sized Array Type) <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160208/009520.html>
Motivation

Fixed-size arrays in C structures are imported as tuples. This means that on the Swift side, developers therefore lose the ability to use even the most basic collection type operations on them, like subscripts. When collection operations are needed, it is usually necessary to transform the tuple into a full-fledged Swift Array using unsafe pointers.

Proposed solution

This proposal suggests adding CollectionType conformance to uniform tuples.

Detailed design

Any tuple of more than one element, in which every element has the same type, is eligible for CollectionType conformance. CollectionType elements are generated as such:

Generator: opaque. Possibly based off UnsafeBufferPointers, possibly the same for all uniform tuples (to a generic parameter).
Index: Int.
SubSequence: Array, since tuples are value types and cannot be shared without being copied wholesale anyway, and the dynamic nature of SubSequence means that it usually is impossible to simply return a smaller tuple (whose size has to be known at compile-time).
count: the number of elements in the tuple.
first: tuple.0
isEmpty: false
subscript(_: Self.Index): single element at given index. Bounds-checked.
subscript(_: Range<Self.Index>): sub-sequence Array. Bounds-checked.
startIndex: 0.
endIndex: count.
It is worth noting that uniform tuples do not lose static field access. This avoids needlessly breaking existing code and allows developers to bypass bounds-checking for indices known to be safe.

Impact on existing code

No impact on existing code; the feature is purely additive.

Alternatives considered

A simpler syntax to declare uniform tuples from Swift, like (Int x 4), was found to be contentious. This proposal forks off the original for incremental implementation of the feature.

The original proposal only called for a subscript on uniform tuples. Adding full CollectionType support seemed simple enough and useful enough to suggest it.

It was suggested that uniform tuples should lose their static field access syntax to ensure that there is Just One Way to access tuple elements. However, this could have surprising side effects on existing code and wouldn't be possible with generic code.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Thorsten Seitz) #6

Looks good to me!

I’m all for keeping the static field access, too, because dropping it would mean having two very different kinds of tuples.

If Swift should ever get union types this proposal can seamlessly be extended to heterogenous tuples which would then conform to CollectionType like proposed but just with an Element type equal to the union of all types present in the tuple.

-Thorsten

···

Am 11.02.2016 um 18:12 schrieb Félix Cloutier via swift-evolution <swift-evolution@swift.org>:

Hi all,

Since the original fixed-size array thread is somewhat stalling, I forked off the subscript part into this: Treat uniform tuples as collections <https://github.com/zneak/swift-evolution/blob/uniform-tuples/proposals/00nn-collectiontype-for-tuples.md>

Félix

Treat uniform tuples as collections

Proposal: SE-NNNN <https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md>
Author(s): Swift Developer <https://github.com/swiftdev>
Status: Awaiting review
Review manager: TBD

Introduction

This proposal aims at adding collection operations to uniform tuples: tuples in which every element has the same type, and no element has a label.

Swift-evolution thread: Proposal: Contiguous Variables (A.K.A. Fixed Sized Array Type) <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160208/009520.html>
Motivation

Fixed-size arrays in C structures are imported as tuples. This means that on the Swift side, developers therefore lose the ability to use even the most basic collection type operations on them, like subscripts. When collection operations are needed, it is usually necessary to transform the tuple into a full-fledged Swift Array using unsafe pointers.

Proposed solution

This proposal suggests adding CollectionType conformance to uniform tuples.

Detailed design

Any tuple of more than one element, in which every element has the same type, is eligible for CollectionType conformance. CollectionType elements are generated as such:

Generator: opaque. Possibly based off UnsafeBufferPointers, possibly the same for all uniform tuples (to a generic parameter).
Index: Int.
SubSequence: Array, since tuples are value types and cannot be shared without being copied wholesale anyway, and the dynamic nature of SubSequence means that it usually is impossible to simply return a smaller tuple (whose size has to be known at compile-time).
count: the number of elements in the tuple.
first: tuple.0
isEmpty: false
subscript(_: Self.Index): single element at given index. Bounds-checked.
subscript(_: Range<Self.Index>): sub-sequence Array. Bounds-checked.
startIndex: 0.
endIndex: count.
It is worth noting that uniform tuples do not lose static field access. This avoids needlessly breaking existing code and allows developers to bypass bounds-checking for indices known to be safe.

Impact on existing code

No impact on existing code; the feature is purely additive.

Alternatives considered

A simpler syntax to declare uniform tuples from Swift, like (Int x 4), was found to be contentious. This proposal forks off the original for incremental implementation of the feature.

The original proposal only called for a subscript on uniform tuples. Adding full CollectionType support seemed simple enough and useful enough to suggest it.

It was suggested that uniform tuples should lose their static field access syntax to ensure that there is Just One Way to access tuple elements. However, this could have surprising side effects on existing code and wouldn't be possible with generic code.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(David Sweeris) #7

I know their syntaxes are different, but aside from "cleverness" involving a union's memory layout and such, what can you do with a union that you can't do with an enum w/ associated values?

- Dave Sweeris

···

On Feb 11, 2016, at 10:35, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:

If Swift should ever get union types this proposal can seamlessly be extended to heterogenous tuples which would then conform to CollectionType like proposed but just with an Element type equal to the union of all types present in the tuple.

-Thorsten

Am 11.02.2016 um 18:12 schrieb Félix Cloutier via swift-evolution <swift-evolution@swift.org>:

Hi all,

Since the original fixed-size array thread is somewhat stalling, I forked off the subscript part into this: Treat uniform tuples as collections

Félix

Treat uniform tuples as collections
Proposal: SE-NNNN
Author(s): Swift Developer
Status: Awaiting review
Review manager: TBD
Introduction

This proposal aims at adding collection operations to uniform tuples: tuples in which every element has the same type, and no element has a label.

Swift-evolution thread: Proposal: Contiguous Variables (A.K.A. Fixed Sized Array Type)

Motivation

Fixed-size arrays in C structures are imported as tuples. This means that on the Swift side, developers therefore lose the ability to use even the most basic collection type operations on them, like subscripts. When collection operations are needed, it is usually necessary to transform the tuple into a full-fledged Swift Array using unsafe pointers.

Proposed solution

This proposal suggests adding CollectionType conformance to uniform tuples.

Detailed design

Any tuple of more than one element, in which every element has the same type, is eligible for CollectionType conformance. CollectionType elements are generated as such:

Generator: opaque. Possibly based off UnsafeBufferPointers, possibly the same for all uniform tuples (to a generic parameter).
Index: Int.
SubSequence: Array, since tuples are value types and cannot be shared without being copied wholesale anyway, and the dynamic nature of SubSequence means that it usually is impossible to simply return a smaller tuple (whose size has to be known at compile-time).
count: the number of elements in the tuple.
first: tuple.0
isEmpty: false
subscript(_: Self.Index): single element at given index. Bounds-checked.
subscript(_: Range<Self.Index>): sub-sequence Array. Bounds-checked.
startIndex: 0.
endIndex: count.
It is worth noting that uniform tuples do not lose static field access. This avoids needlessly breaking existing code and allows developers to bypass bounds-checking for indices known to be safe.

Impact on existing code

No impact on existing code; the feature is purely additive.

Alternatives considered

A simpler syntax to declare uniform tuples from Swift, like (Int x 4), was found to be contentious. This proposal forks off the original for incremental implementation of the feature.

The original proposal only called for a subscript on uniform tuples. Adding full CollectionType support seemed simple enough and useful enough to suggest it.

It was suggested that uniform tuples should lose their static field access syntax to ensure that there is Just One Way to access tuple elements. However, this could have surprising side effects on existing code and wouldn't be possible with generic code.
_______________________________________________
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


(Félix Cloutier) #8

How realistic is it to also have a `count` getter? If we can't have `for elem in tuple`, at least that would allow `for i in 0..<tuple.count`.

Félix

···

Le 11 févr. 2016 à 15:38:07, Chris Lattner <clattner@apple.com> a écrit :

On Feb 11, 2016, at 10:59 AM, Douglas Gregor via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Feb 11, 2016, at 9:12 AM, Félix Cloutier via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Hi all,

Since the original fixed-size array thread is somewhat stalling, I forked off the subscript part into this: Treat uniform tuples as collections <https://github.com/zneak/swift-evolution/blob/uniform-tuples/proposals/00nn-collectiontype-for-tuples.md>

This specific proposal is a non-starter for me, because it lands squarely in the "death valley" of being extremely invasive on the implementation while providing only a small amount of relative value.

I agree with Doug on this. I still think the right approach is to:

1) add a subscript on tuples with a consistent element kind.
2) add some type sugar for defining these types
3) consider a convenient form for defining an initializer on these.

To me, that is the order of priority. Just getting #1 and #2 would seriously move the needle on making C arrays work better, with very little implementation complexity. #3 would be nice, but seems less important.

-Chris


(Thorsten Seitz) #9

I know their syntaxes are different, but aside from "cleverness" involving a union's memory layout and such, what can you do with a union that you can't do with an enum w/ associated values?

This, for example:

interface Set<These> {
    shared formal Set<These | Those> union<Those>(Set<Those> set);
    shared formal Set<These & Those> intersection<Those>(Set<Those> set);
}

Taken from Gavin King's talk (idiom #7 and #8) here:
https://1bee51e9-a-62cb3a1a-s-sites.googlegroups.com/site/jugffm/home/04062014-ceylon-introduction/Ceylon%20German%20JUGs.pdf

-Thorsten

···

Am 11.02.2016 um 20:30 schrieb David Sweeris <davesweeris@mac.com>:

- Dave Sweeris

On Feb 11, 2016, at 10:35, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:

If Swift should ever get union types this proposal can seamlessly be extended to heterogenous tuples which would then conform to CollectionType like proposed but just with an Element type equal to the union of all types present in the tuple.

-Thorsten

Am 11.02.2016 um 18:12 schrieb Félix Cloutier via swift-evolution <swift-evolution@swift.org>:

Hi all,

Since the original fixed-size array thread is somewhat stalling, I forked off the subscript part into this: Treat uniform tuples as collections

Félix

Treat uniform tuples as collections
Proposal: SE-NNNN
Author(s): Swift Developer
Status: Awaiting review
Review manager: TBD
Introduction

This proposal aims at adding collection operations to uniform tuples: tuples in which every element has the same type, and no element has a label.

Swift-evolution thread: Proposal: Contiguous Variables (A.K.A. Fixed Sized Array Type)

Motivation

Fixed-size arrays in C structures are imported as tuples. This means that on the Swift side, developers therefore lose the ability to use even the most basic collection type operations on them, like subscripts. When collection operations are needed, it is usually necessary to transform the tuple into a full-fledged Swift Array using unsafe pointers.

Proposed solution

This proposal suggests adding CollectionType conformance to uniform tuples.

Detailed design

Any tuple of more than one element, in which every element has the same type, is eligible for CollectionType conformance. CollectionType elements are generated as such:

Generator: opaque. Possibly based off UnsafeBufferPointers, possibly the same for all uniform tuples (to a generic parameter).
Index: Int.
SubSequence: Array, since tuples are value types and cannot be shared without being copied wholesale anyway, and the dynamic nature of SubSequence means that it usually is impossible to simply return a smaller tuple (whose size has to be known at compile-time).
count: the number of elements in the tuple.
first: tuple.0
isEmpty: false
subscript(_: Self.Index): single element at given index. Bounds-checked.
subscript(_: Range<Self.Index>): sub-sequence Array. Bounds-checked.
startIndex: 0.
endIndex: count.
It is worth noting that uniform tuples do not lose static field access. This avoids needlessly breaking existing code and allows developers to bypass bounds-checking for indices known to be safe.

Impact on existing code

No impact on existing code; the feature is purely additive.

Alternatives considered

A simpler syntax to declare uniform tuples from Swift, like (Int x 4), was found to be contentious. This proposal forks off the original for incremental implementation of the feature.

The original proposal only called for a subscript on uniform tuples. Adding full CollectionType support seemed simple enough and useful enough to suggest it.

It was suggested that uniform tuples should lose their static field access syntax to ensure that there is Just One Way to access tuple elements. However, this could have surprising side effects on existing code and wouldn't be possible with generic code.
_______________________________________________
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


(Brent Royal-Gordon) #10

How realistic is it to also have a `count` getter? If we can't have `for elem in tuple`, at least that would allow `for i in 0..<tuple.count`.

I do want a way to get the count (or you could call it the arity, doesn't really matter). The syntax is a bit of an issue, though. Four suggestions, each annotated with its flaw:

  typealias FourInts = (4 x Int)
  let fourInts = (1, 2, 3, 4)
  
  fourInts.arity // might interfere with tuples that have an element labeled `arity`
  FourInts.arity // didn't someone say SIL has trouble with things like properties on compound types?
  arity(FourInts) // this is known at compile time, no need for a runtime function call
  #arity(FourInts) // hash is kind of gross, and I'm currently suspicious of all hash proposals

···

--
Brent Royal-Gordon
Architechies