Skip to content

Commit 1fb3715

Browse files
hartbitDougGregor
authored andcommitted
More Powerful Constraints for Associated Types (#284)
* formalized proposal already discussed * added more details pertaining to constraints on parent associated types * added examples to name lookup * nitpick * Rename for more clarity * Improvements after comments from @dabrahams * Updated links to mailinglist instead of gmane * Updated header format and email links * escaped the `where` keyword * Minor corrections suggested by @dabrahams * Added paragraph on ABI stability
1 parent 43b625c commit 1fb3715

File tree

1 file changed

+107
-0
lines changed

1 file changed

+107
-0
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Permit where clauses to constrain associated types
2+
3+
* Proposal: [SE-NNNN](NNNN-associated-types-constraints.md)
4+
* Authors: [David Hart](https://github.com/hartbit), [Jacob Bandes-Storch](https://github.com/jtbandes), [Doug Gregor](https://github.com/DougGregor)
5+
* Review Manager: TBD
6+
* Status: **Awaiting review**
7+
8+
## Introduction
9+
10+
This proposal seeks to introduce a `where` clause to associated type
11+
declarations and improvements to protocol constraints to bring associated types
12+
the same expressive power as generic type parameters.
13+
14+
This proposal was discussed twice on the Swift Evolution list in the following
15+
threads:
16+
17+
* [\[Completing Generics\] Arbitrary requirements in protocols](https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160411/014667.html)
18+
* [Proposal] More Powerful Constraints for Associated Types
19+
- [Week #1](https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160418/015625.html)
20+
- [Week #2](https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160425/015753.html)
21+
- [Week #3](https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160502/016354.html)
22+
23+
## Motivation
24+
25+
Currently, associated type declarations can only express simple inheritance
26+
constraints and not the more sophisticated constraints available to generic
27+
types with the `where` clause. Some designs, including many in the Standard
28+
Library, require more powerful constraints for associated types to be truly
29+
elegant. For example, the `SequenceType` protocol could be declared as follows
30+
if the current proposal was accepted:
31+
32+
```swift
33+
protocol Sequence {
34+
associatedtype Iterator : IteratorProtocol
35+
associatedtype SubSequence : Sequence where SubSequence.Iterator.Element == Iterator.Element
36+
...
37+
}
38+
```
39+
40+
## Detailed Design
41+
42+
First of all, this proposal modifies the grammar for a protocol's associated types
43+
to the following:
44+
45+
*protocol-associated-type-declaration*
46+
*attributes<sub>opt</sub>*
47+
*access-level-modifier<sub>opt</sub>*
48+
**associatedtype**
49+
*typealias-name*
50+
­*type-inheritance-clause­<sub>opt</sub>*
51+
*typealias-assignment­<sub>opt</sub>*
52+
*requirement-clause<sub>opt</sub>*
53+
54+
The new requirement-clause is then used by the compiler to validate the
55+
associated types of conforming types.
56+
57+
Secondly, the proposal also allows protocols to use the associated types of
58+
their conforming protocols in their declaration `where` clause as below:
59+
60+
```swift
61+
protocol IntSequence : Sequence where Iterator.Element == Int {
62+
...
63+
}
64+
```
65+
66+
Name lookup semantics in the protocol declaration `where` clause only looks at
67+
associated types in the parent protocols. For example, the following code would
68+
cause an error:
69+
70+
```swift
71+
protocol SomeSequence : Sequence where Counter : SomeProtocol { // error: Use of undefined associated type 'Counter'
72+
associatedtype Counter
73+
}
74+
```
75+
76+
But instead should be written on the associated type itself:
77+
78+
```swift
79+
protocol IntSequence : Sequence {
80+
associatedtype Counter : SomeProtocol
81+
}
82+
```
83+
84+
## Effect on ABI Stability
85+
86+
As mentioned previously, there are a number of places in the standard library where this feature would be adopted (such as the `SubSequence.Iterator.Element == Iterator.Element` example), each of which will change the mangling of any generic function/type that makes use of them.
87+
88+
## Alternatives
89+
90+
Douglas Gregor argues that the proposed syntax is redundant when adding new
91+
constraints to an associated type declared in a parent protocol and proposes
92+
another syntax:
93+
94+
```swift
95+
protocol Collection : Sequence {
96+
where SubSequence : Collection
97+
}
98+
```
99+
100+
But as Douglas notes himself, that syntax is ambiguous since we adopted the
101+
generic `where` clause at the end of declarations of the following proposal:
102+
[SE-0081: Move where clause to end of declaration](https://github.com/apple/swift-evolution/blob/master/proposals/0081-move-where-expression.md). For those reasons, it might be wiser not to introduce the shorthand syntax.
103+
104+
## Acknowledgements
105+
106+
Thanks to Dave Abrahams and Douglas Gregor for taking the time to help me
107+
through this proposal.

0 commit comments

Comments
 (0)