You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To achieve the goal of using variadic generics to generalize structural types, this design includes the ability to expand tuple values into a list of individual element types, unlocking all the same expressivity for tuples without introducing an additional set of operations for mapping, iteration, concatenation, and de-structuring.
286
+
To achieve the goal of using variadic generics to generalize tuple types, this design includes the ability to access the elements of a tuple value as a value pack, unlocking all the same expressivity for tuples without introducing an additional set of operations for mapping, iteration, concatenation, and de-structuring.
287
287
288
-
An abstract tuple value contains a list of zero or more individual values. The *value expansion operator*, spelled with `...`, removes the tuple structure, leaving a comma-separated list of zero or more individual values that can be used anywhere that accepts a value pack expansion:
288
+
An abstract tuple value contains a list of zero or more individual values. Packing the elements of a tuple removes the tuple structure, and collects the individual tuple elements into a value pack. This operation is a special property on tuple types called `.element`:
289
289
290
290
```swift
291
291
structMapped<Value> {}
292
292
293
293
funcmap<T...>(tuple: (T...)) -> (Mapped<T>...) {
294
-
let element = tuple...// expands 'tuple' into a local variable pack
295
-
return (Mapped(element)...)
294
+
return (Mapped(tuple.element)...)
296
295
}
297
296
```
298
297
299
-
Similar to concrete value packs, using the value expansion operator on concrete or partially concrete tuples requires a type annotation for the abstract element type:
298
+
The `element` property returns the elements of a tuple in a single pack. For an abstract tuple `(T...)`, the signature of this property is `(T...) -> T`, which is otherwise not expressible in the language. For a tuple of length *n*, the complexity of converting a tuple value to a pack is *O(n)*.
299
+
300
+
Similar to concrete value packs, using the pack operation on concrete or partially concrete tuples requires a type annotation for the abstract element type:
300
301
301
302
```swift
302
303
funciterate(overtuple: (Int, String, Bool)) {
303
-
for value: some Equatablein tuple... {
304
+
for value: some Equatablein tuple.element... {
304
305
// do something with an 'Equatable' value
305
306
}
306
307
}
307
308
```
308
309
309
-
To express individual tuple elements in repetition patterns, e.g. to expand the elements of a tuple in parallel with a pack or another tuple, the tuple must first be expanded into a local variable pack. This may become a common pattern in variadic generic code, and it may be useful to add an explicit operator to turn a tuple value into a pack directly in the pattern of a pack expansion. For illustrative purposes, a possible syntax for converting a tuple to a pack without an intermediate local variable is `tuple as T` where `T` is a reference to a type pack:
310
-
311
-
```swift
312
-
funcmap<T...>(tuple: (T...)) -> (T?...) {
313
-
return ((tuple as T)?...)
314
-
}
315
-
```
316
-
317
310
### User-defined tuple conformances
318
311
319
312
The above features together provide the necessary tools for writing abstractions over tuples with variable length. The last major expressivity gap between tuples and nominal types is the ability to declare conformances on tuples. This design finally closes that gap, using a parameterized extension syntax to declare the conformance:
@@ -384,13 +377,12 @@ Packs can also be used in the parameter list of a function type; if packs were t
384
377
385
378
## Exploring syntax alternatives
386
379
387
-
This design for variadic generics results introduces 3 new meanings of `...`, leaving Swift with 5 total meanings of `...`:
380
+
This design for variadic generics results introduces 2 new meanings of `...`, leaving Swift with 4 total meanings of `...`:
388
381
389
382
1. Non-pack variadic parameters
390
383
2. Postfix partial range operator
391
384
3. Type parameter pack declaration
392
385
4. Pack expansion operator
393
-
5. Value expansion operator
394
386
395
387
Choosing an alternative syntax may alleviate ambiguities with existing meanings of ... in Swift. The authors of this vision document are open to considering an alternative syntax, but have yet to find a more compelling one.
0 commit comments