Skip to content
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 Sep 28, 2022
5c536d6
Fix the type of postfix ... operator in the ambiguity example.
hborla Sep 29, 2022
5c05e76
update pitch (#1)
slavapestov Oct 25, 2022
1b7259e
Add missing SE proposal information.
hborla Oct 26, 2022
3fc7be5
Replace the '...' syntax with 'repeat each'.
hborla Feb 20, 2023
09e11cf
Add more introductory explanation to the proposed solution.
hborla Feb 20, 2023
b2ea985
Update proposals/NNNN-parameter-packs.md
hborla Feb 24, 2023
7825076
Address editorial feedback
hborla Mar 8, 2023
5940dc2
Add pack iteration and pack element projection to the future directions.
hborla Mar 8, 2023
d3043f8
Move local value packs and add explicit pack syntax to future directi…
hborla Mar 8, 2023
38c3871
Describe single-element tuple unwrapping under pack substitution.
hborla Mar 14, 2023
80b0888
Simplify the description of same-type requirements involving paramete…
hborla Mar 14, 2023
fcc02ba
Update proposals/NNNN-parameter-packs.md
hborla Mar 14, 2023
f974506
Move the introduction above the table of contents.
hborla Mar 15, 2023
247284d
Specify trailing closure matching rules for parameter packs.
hborla Mar 15, 2023
fe936ab
Replace the term "type sequence" with "type list" to avoid confusion …
hborla Mar 15, 2023
32b13db
Add more commentary on the `repeat each` syntax design.
hborla Mar 15, 2023
944432a
Minor editorial changes
hborla Mar 15, 2023
ab18ee4
Describe how variadic generic functions interact with overload resolu…
hborla Mar 15, 2023
0aeb480
Update pitch links.
hborla Mar 15, 2023
1c1b51c
Update 0393-parameter-packs.md
xwu Mar 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Simplify the description of same-type requirements involving paramete…
…r packs.
  • Loading branch information
hborla committed Mar 15, 2023
commit 80b0888ca8254152f4d6bf669320bb1e20b9dc3b
48 changes: 13 additions & 35 deletions proposals/NNNN-parameter-packs.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,47 +365,28 @@ All existing kinds of generic requirements generalize to type parameter packs. S
func variadic<each S>(_: repeat each S) where each S: Sequence { ... }
```

A valid substitution for the above might replace `S` with `{Array<Int>, Set<String>}`.
A valid substitution for the above might replace `S` with `{Array<Int>, Set<String>}`. Expanding the substitution into the requirement `each S: Sequence` conceptually produces the following conformance requirements: `Array<Int>: Sequence, Set<String>: Sequence`.

2. A same-type requirement where one side is a type parameter pack and the other type is a concrete type that does not capture any type parameter packs is interpreted as constraining each element of the replacement type pack to _the same_ concrete type:
2. A same-type requirement where one side is a type parameter pack and the other type is a scalar type that does not capture any type parameter packs is interpreted as constraining each element of the replacement type pack to _the same_ scalar type:

```swift
func variadic<each S: Sequence, T>(_: repeat each S) where (each S).Element == T {}
```

This is called a _concrete same-element requirement_.
This is called a _same-element requirement_.

A valid substitution for the above might replace `S` with `{Array<Int>, Set<Int>}`, and `T` with `Int`.

3. A same-type requirement where one side is a type parameter pack and the other type is a scalar type parameter is interpreted as constraining each element of the replacement type pack to the type parameter:

```swift
func variadic<each S: Sequence, each T>(_: repeat each S) where (each S).Element == each T {}
```

This is called an _abstract same-element requirement_.

A valid substitution for the above might replace `S` with `{Array<Int>, Set<String>}`, and `T` with `{Int, String}`.

4. A same-type requirement where one side is a type parameter pack and the other side is a concrete type capturing at least one type parameter pack is interpreted as expanding the concrete type and constraining each element of the replacement type pack to the concrete element type:
3. A same-type requirement where each side is a pattern type that captures at least one type parameter pack is interpreted as expanding the type packs on each side of the requirement, equating each element pair-wise.

```swift
func variadic<each S: Sequence, each T>(_: repeat each S) where (each S).Element == Array<each T> {}
```

This is called a _concrete same-type pack requirement_.

A valid substitution for the above might replace `S` with `{Array<Array<Int>>, Set<Array<String>>}`, and `T` with `{Int, String}`.
This is called a _same-type-pack requirement_.

5. A same-type requirement where both sides are type parameter packs constrains the elements of the replacement type pack element-wise:

```swift
func append<each S: Sequence, each T: Sequence>(_: repeat each S, _: repeat each T) where (each T).Element == (each S).Element {}
```

This is called an _abstract same-type pack requirement_.

A valid substitution for the above would replace `S` with `{Array<Int>, Set<String>}`, and `T` with `{Set<Int>, Array<String>}`.
A valid substitution for the above might replace `S` with `{Array<Array<Int>>, Set<Array<String>>}`, and `T` with `{Int, String}`. Expanding `(each S).Element == Array<each T>` will produce the following list of same-type requirements: `Array<Array<Int>.Element == Array<Int>, Set<Array<String>>.Element == String`.

There is an additional kind of requirement called a _same-shape requirement_. There is no surface syntax for spelling a same-shape requirement; they are always inferred, as described in the next section.

Expand All @@ -417,22 +398,19 @@ There is an additional kind of requirement called a _same-shape requirement_. Th

A same-shape requirement states that two type parameter packs have the same number of elements, with pack expansion types occurring at identical positions.

At this time, we are not proposing a spelling for same-shape requirements in the surface language, since we do not believe it is necessary given the inference behavior outlined below. However, we will use the notation `shape(T) == shape(U)` to denote same-shape requirements in this proposal.
This proposal does not include a spelling for same-shape requirements in the surface language; same-shape requirements are always inferred, and an explicit same-shape requirement syntax is a future direction. However, we will use the notation `shape(T) == shape(U)` to denote same-shape requirements in this proposal.

A same-shape requirement always relates two root type parameter packs. Member types always have the same shape as the root type parameter pack, so `shape(T.A) == shape(U.B)` reduces to `shape(T) == shape(U)`.

**Inference:** Same-shape requirements are inferred in one of three ways:

1. An abstract same-type requirement implies a same-shape requirement between two type parameter packs.

2. A concrete same-type requirement implies a same-shape requirement between the type parameter packs on the left hand side and all type parameter packs captured by the concrete type on the right hand side.
**Inference:** Same-shape requirements are inferred in the following ways:

3. Finally, a same-shape requirement is inferred between each pair of type parameter packs captured by a pack expansion type appearing in certain positions.
1. A same-type-pack requirement implies a same-shape requirement between all type parameter packs captured by the pattern types on each side of the requirement.

The following positions are subject to the same-shape requirement inference in Case 3:
For example, given the parameter packs `<each First, each Second, each S: Sequence>`, the same-type-pack requirement `Pair<each First, each Second> == (each S).Element` implies `shape(First) == shape(Second), shape(First) == shape(S), shape(Second) == shape(S)`.

* all types appearing in the requirements of a trailing `where` clause of a generic function
* the parameter types and return type of a generic function
2. A same-shape requirement is inferred between each pair of type parameter packs captured by a pack expansion type appearing in the following positions
* all types appearing in the requirements of a trailing `where` clause of a generic function
* the parameter types and the return type of a generic function

Recall that if the pattern of a pack expansion type contains more than one type parameter pack, all type parameter packs must be known to have the same shape, as outlined in the [Type substitution](#type-substitution) section. Same-shape requirement inference ensures that these invariants are satisfied when the pack expansion type occurs in one of the two above positions.

Expand Down