Skip to content

Commit 1cecd8a

Browse files
committed
Adding SE-0095 version 2 proposal
1 parent a4356fe commit 1cecd8a

File tree

1 file changed

+31
-35
lines changed

1 file changed

+31
-35
lines changed

proposals/0095-any-as-existential.md

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,74 @@
1-
# Replace `protocol<P1,P2>` syntax with `Any<P1,P2>`
1+
# Replace `protocol<P1,P2>` syntax with `P1 & P2` syntax
22

33
* Proposal: [SE-0095](0095-any-as-existential.md)
44
* Author: [Adrian Zubarev](https://github.com/DevAndArtist), [Austin Zheng](https://github.com/austinzheng)
5-
* Status: **Returned for Revision** [Rationale](https://lists.swift.org/pipermail/swift-evolution-announce/2016-June/000182.html)
5+
* Status: **TBD**
66
* Review manager: [Chris Lattner](http://github.com/lattner)
7+
* Revision: 2
8+
* Previous Revisions: [1](https://github.com/apple/swift-evolution/blob/a4356fee94c06181715fad83aa61e923eb73f8ec/proposals/0095-any-as-existential.md)
79

810
## Introduction
911

10-
The current `protocol<>` construct, which defines an existential type consisting of zero or more protocols, should be renamed `Any<>`.
12+
The current `protocol<>` construct, which defines an existential type consisting of zero or more protocols, should be replaced by an infix `&` type operator joining bare protocol type names.
1113

12-
[Discussion thread](https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160516/018109.html)
14+
Discussion threads: [pre-proposal](https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160516/018109.html), [review thread 1](http://thread.gmane.org/gmane.comp.lang.swift.evolution/18349), [2](http://thread.gmane.org/gmane.comp.lang.swift.evolution/18350/focus=18447), [3](http://thread.gmane.org/gmane.comp.lang.swift.evolution/18351/focus=18440), [4](http://thread.gmane.org/gmane.comp.lang.swift.evolution/18518), [post-review thread](http://thread.gmane.org/gmane.comp.lang.swift.evolution/19463)
1315

1416
## Motivation
1517

1618
A stated goal for Swift 3.0 is making breaking changes to prepare the way for features to be introduced in future features, especially those involving the enhancements to the generics system detailed in [*Completing Generics*](https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md).
1719

18-
One such change described in *Completing Generics* is renaming `protocol<>` to `Any<>` in order to allow it to serve as a syntactic foundation for more generalized existential types. This is a straightforward change which will allow a later version of Swift to introduce better handling for existential types without making breaking changes, or changes whose functionality overlaps with that of existing features.
20+
One such change described in *Completing Generics* is improving the existing `protocol<>` syntax in order to allow it to serve as a syntactic foundation for more generalized existential types. This is a straightforward change which will allow a later version of Swift to introduce better handling for existential types without making breaking changes, or changes whose functionality overlaps with that of existing features.
1921

2022
## Proposed solution
2123

22-
The `protocol<...>` construct should be replaced with the `Any<...>` construct, where one or more protocol names can be inserted between the angle brackets to denote protocol composition. There will be no changes to the behavior of `Any<...>` relative to `protocol<...>`.
24+
The `protocol<...>` construct should be removed. In its place, an infix type operator `&` will be introduced.
2325

24-
`Any` will retain the same function and behavior as it did prior to Swift 3.0. `Any<>` will be forbidden. An error message can direct users to use `Any` instead of `Any<>`.
26+
An existential type comprised of more than one protocol will be defined by listing its types, separated by the `&` operator, as shown below in the examples.
27+
28+
The existing `Any` typealias, which represents all types that conform to zero or more protocols (i.e. all types), will become a keyword. Its meaning will not change.
2529

2630
Trivial example:
2731

2832
```swift
2933
protocol A { }
3034
protocol B { }
35+
protocol C { }
3136

32-
struct Foo : A, B { }
37+
struct Foo : A, B, C { }
3338

34-
let a : Any<A, B> = Foo()
39+
let a : A & B & C = Foo()
3540
```
3641

37-
## Impact on existing code
38-
39-
Programmers will need to update any code using `protocol<...>` (this can be done with a simple find and replace operation). Code that uses `Any`, but no protocol composition, will be unaffected. Code that happens to use `protocol<>` must be changed to use `Any` instead.
40-
41-
## Alternatives considered
42-
43-
A couple of alternative options for proposal details follow.
44-
45-
* The original proposal allowed both `Any<>` and `Any`. However, community members brought up concerns regarding the fact that there were two nearly-identical representations for the 'any type' existential, and that there could possibly be issues cleanly defining the grammar or implementing the parser to properly handle both cases.
42+
Example with functions:
4643

47-
### `Any` vs `any`
44+
```swift
45+
protocol A { }
46+
protocol B { }
4847

49-
A discussion took place among swift-evolution participants as to whether or not the keyword for this feature should be `Any` or `any`. This proposal presents `Any`, but also lists reasons provided in favor of both options below, with the hope that the proposal review discussion and core team can choose the best option.
48+
// Existential
49+
func firstFunc(x: A & B) { ... }
5050

51-
**For `Any<P1, P2>`**:
51+
// Generic
52+
func secondFunc<T : A & B>(x: T) { ... }
53+
```
5254

53-
* The convention is to capitalize types. `Any<A, B>` is immediately apparent as a type, and looks like a type when used in places where types would be used (like function signatures).
54-
* Having `Any<A, B>` allows us to keep the well-established `Any` without having to typealias to `any` or `any<>` forms.
55-
* `any` is a keyword, but an argument can be made that keywords that fit into a particular syntactic slot should be capitalized like normal members of that slot. `Any<...>` fits into the slot of identifiers used as types, so it should be named like a type.
56-
* In the future, `AnySequence` and similar type-erased wrappers can be replaced with, e.g. `Any<Sequence>`. This increases discoverability of existential features, like a future `Any<Sequence where .Element == String>`. It's possible this will increase awareness and use of `Any<...>` over that of `protocol<>`, which is difficult to discover.
55+
The use of `&` instead of `,` more clearly conveys the intent of the syntactic construct: defining a composite type formed from the conjunction of two or more protocol types.
5756

58-
**For `any<P1, P2>`**:
57+
## Impact on existing code
5958

60-
* `any<...>`'s lower case 'a' distinguishes it from other generic types that use similar syntax, such as `Array<Int>`. Perhaps developers, especially those new to Swift, will be confused as to why `Any<A, B>` isn't a generic type, but `Dictionary<A, B>` is. Even without considering new developers, it can be jarring to have to mentally make the context switch between `Any<A, B>` as an existential, and `AnythingButAny<A, B>` as a generic type.
61-
* `any<...>`'s lower case 'a' makes it clear to users it is not equivalent to a standard user-defined type, but rather a construction that can be used as a type in some cases, and can't be used everywhere a user-defined type can.
62-
* `any<...>` isn't a specific type - it's a kind of type (an existential), and this spelling fits better with the other 'kind' names: `class`, `struct`, `enum`, `protocol`
63-
* `any` is a keyword, and a convention has been established that keywords are lower case without initial or CamelCase-style capitalization. It is important to be consistent in this matter.
59+
Programmers will need to update any code using `protocol<...>`. Code that uses `Any`, but no protocol composition, will be unaffected. Code that happens to use `protocol<>` must be changed to use `Any` instead.
6460

65-
### Alternatives to entire proposal
61+
## Future directions
6662

67-
A couple alternatives to this entire proposal follow.
63+
Whenever a [generalized existential](https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#generalized-existentials) proposal is prepared, the syntax established by this proposal can be extended as appropriate to cover additional functionality (such as `where` clauses).
6864

69-
* Leave `protocol<>` as-is, and decide whether to change it after Swift 3.0 ships. This has the disadvantage of introducing a breaking source change.
65+
## Alternatives considered
7066

71-
* Decide before Swift 3.0 ships that generalized existentials should be defined using a syntax besides the `protocol<>` or `Any<>` syntaxes, and adopt that syntax instead. Disadvantages: core team has no bandwidth to consider changes of this scope at the current time.
67+
The original proposal suggested replacing `protocol<>` with either `Any<>` or `any<>`.
7268

7369
## Acknowledgements
7470

75-
[Matthew Johnson](https://github.com/anandabits) and [Brent Royal-Gordon](https://github.com/brentdax) provided valuable input which helped shape this proposal.
71+
[Matthew Johnson](https://github.com/anandabits) and [Brent Royal-Gordon](https://github.com/brentdax) provided valuable input which helped shape the first version of this proposal.
7672

7773
-------------------------------------------------------------------------------
7874

0 commit comments

Comments
 (0)