-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Value and type parameter packs. #1956
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
c9574be
Add a draft proposal for parameter packs.
hborla 5c536d6
Fix the type of postfix ... operator in the ambiguity example.
hborla 5c05e76
update pitch (#1)
slavapestov 1b7259e
Add missing SE proposal information.
hborla 3fc7be5
Replace the '...' syntax with 'repeat each'.
hborla 09e11cf
Add more introductory explanation to the proposed solution.
hborla b2ea985
Update proposals/NNNN-parameter-packs.md
hborla 7825076
Address editorial feedback
hborla 5940dc2
Add pack iteration and pack element projection to the future directions.
hborla d3043f8
Move local value packs and add explicit pack syntax to future directi…
hborla 38c3871
Describe single-element tuple unwrapping under pack substitution.
hborla 80b0888
Simplify the description of same-type requirements involving paramete…
hborla fcc02ba
Update proposals/NNNN-parameter-packs.md
hborla f974506
Move the introduction above the table of contents.
hborla 247284d
Specify trailing closure matching rules for parameter packs.
hborla fe936ab
Replace the term "type sequence" with "type list" to avoid confusion …
hborla 32b13db
Add more commentary on the `repeat each` syntax design.
hborla 944432a
Minor editorial changes
hborla ab18ee4
Describe how variadic generic functions interact with overload resolu…
hborla 0aeb480
Update pitch links.
hborla 1c1b51c
Update 0393-parameter-packs.md
xwu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Minor editorial changes
- Loading branch information
commit 944432ab8a4610198da81c5db7a3111f8e2629ea
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,11 +24,11 @@ This proposal adds _type parameter packs_ and _value parameter packs_ to enable | |
| - [Type parameter packs](#type-parameter-packs) | ||
| - [Pack expansion type](#pack-expansion-type) | ||
| - [Type substitution](#type-substitution) | ||
| - [Single-element pack substitution](#single-element-pack-substitution) | ||
| - [Type matching](#type-matching) | ||
| - [Label matching](#label-matching) | ||
| - [Trailing closure matching](#trailing-closure-matching) | ||
| - [Type list matching](#type-list-matching) | ||
| - [Single-element pack substitution](#single-element-pack-substitution) | ||
| - [Member type parameter packs](#member-type-parameter-packs) | ||
| - [Generic requirements](#generic-requirements) | ||
| - [Same-shape requirements](#same-shape-requirements) | ||
|
|
@@ -167,7 +167,6 @@ A pack expansion type, written as `repeat P`, has a *pattern type* `P` and a non | |
| * The type of a parameter in a function type, e.g. `(repeat each T) -> Bool` | ||
| * The type of an unlabeled element in a tuple type, e.g. `(repeat each T)` | ||
|
|
||
|
|
||
| Because pack expansions can only appear in positions that accept a comma-separated list, pack expansion patterns are naturally delimited by either a comma or the end-of-list delimiter, e.g. `)` for call argument lists or `>` for generic argument lists. | ||
|
|
||
| The restriction where only unlabeled elements of a tuple type may have a pack expansion type is motivated by ergonomics. If you could write `(t: repeat each T)`, then after a substitution `T := {Int, String}`, the substituted type would be `(t: Int, String)`. This would be strange, because projecting the member `t` would only produce the first element. When an unlabeled element has a pack expansion type, like `(repeat each T)`, then after the above substitution you would get `(Int, String)`. You can still write `0` to project the first element, but this is less surprising to the Swift programmer. | ||
|
|
@@ -269,6 +268,17 @@ func counts<each T: Collection>(_ t: repeat each T) { | |
|
|
||
| The `count` property on the `Collection` protocol returns `Int`, so the type of the expression `(repeat (each t).count)` is written as the one-element tuple type `(repeat Int)` whose element is the pack expansion type `repeat Int`. While the pattern type `Int` does not capture any type parameter packs, the pack expansion type must still capture `T` to represent the fact that after expansion, the resulting tuple type has the same length as `T`. This kind of pack expansion type can arise during type inference, but it cannot be written in source. | ||
|
|
||
| #### Single-element pack substitution | ||
|
|
||
| If a parameter pack `each T` is substituted with a single element, the parenthesis around `(repeat each T)` are unwrapped to produce the element type as a scalar instead of a one-element tuple type. | ||
|
|
||
| For example, the following substitutions both produce the element type `Int`: | ||
| - Substituting `each T := {Int}` into `(repeat each T)`. | ||
| - Substituting `each T := {}` into `(Int, repeat each T)`. | ||
|
|
||
| Though unwrapping single-element tuples complicates type matching, surfacing single-element tuples in the programming model would icnrease the surface area of the language. One-element tuples would need to be manually unrwapped with `.0` or pattern matching in order to make use of their contents. This unwrapping would clutter up code. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo: icnrease |
||
|
|
||
|
|
||
| ### Type matching | ||
|
|
||
| Recall that the substitutions for a reference to a generic function are derived from the types of call argument expressions together with the contextual return type of the call, and are not explicitly written in source. This necessitates introducing new rules for _matching_ types containing pack expansions. | ||
|
|
@@ -354,19 +364,9 @@ For example, matching `(x: Int, repeat each T, z: String)` against `(x: Int, Dou | |
|
|
||
| However, matching `(x: Int, repeat each T, z: String)` against `(x: Int, Double, Float, z: String)` leaves you with `repeat each T` vs `Double, Float`, which succeeds with `T := {Double, Float}`, because the labels match exactly in the common prefix and suffix, and no labels remain once we get to Case 1 above. | ||
|
|
||
| #### Single-element pack substitution | ||
|
|
||
| If a parameter pack `each T` is substituted with a single element, the parenthesis around `(repeat each T)` are unwrapped to produce the element type as a scalar instead of a one-element tuple type. | ||
|
|
||
| For example, the following substitutions both produce the element type `Int`: | ||
| - Substituting `each T := {Int}` into `(repeat each T)`. | ||
| - Substituting `each T := {}` into `(Int, repeat each T)`. | ||
|
|
||
| Though unwrapping single-element tuples complicates type matching, surfacing single-element tuples in the programming model would icnrease the surface area of the language. One-element tuples would need to be manually unrwapped with `.0` or pattern matching in order to make use of their contents. This unwrapping would clutter up code. | ||
|
|
||
| ### Member type parameter packs | ||
|
|
||
| If a type parameter pack `T` is subject to a protocol conformance requirement `P`, and `P` declares an associated type `A`, then `T.A` is a valid pattern type for a pack expansion type, called a _member type parameter pack_. | ||
| If a type parameter pack `each T` is subject to a protocol conformance requirement `P`, and `P` declares an associated type `A`, then `(each T).A` is a valid pattern type for a pack expansion type, called a _member type parameter pack_. | ||
|
|
||
| Under substitution, a member type parameter pack projects the associated type from each element of the replacement type pack. | ||
|
|
||
|
|
@@ -378,7 +378,7 @@ func variadic<each T: Sequence>(_: repeat each T) -> (repeat (each T).Element) | |
|
|
||
| After the substitution `T := {Array<Int>, Set<String>}`, the substituted return type of this function becomes the tuple type `(Int, String)`. | ||
|
|
||
| We will refer to `T` as the _root type parameter pack_ of the member type parameter packs `T.A` and `T.A.B`. | ||
| We will refer to `each T` as the _root type parameter pack_ of the member type parameter packs `(each T).A` and `(each T).A.B`. | ||
|
|
||
| ### Generic requirements | ||
|
|
||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.