[Returned for Revision] SE-0095: Replace protocol<P1, P2> syntax with Any<P1, P2>


(Chris Lattner) #1

Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0095-any-as-existential.md

Hello Swift Community,

The review of SE-0095: "Replace protocol<P1,P2> syntax with Any<P1,P2>" ran from May 24…30, 2016. The proposal is returned with revision requested - ideally the revised proposal will be included in Swift 3.

There was an incredible amount of feedback from the community, continuing even today. The principle problem identified by community about the proposal is that "Any<T1, T2>” implies very strongly an “any of T1 OR T2” relationship (aka disjunction) and not “any type conforming to T1 AND T2” relationship (aka conjunction). There was also some related discussion as to how the “Any<>” syntax aligns with future generalized existential syntax, much discussion as to whether it should be spelled Any<> or any<>, and some discussion about "angle bracket blindness".

The core team extensively discussed the feedback and considered many different possible paths forward. The conclusion of this is that it recommends that SE-0095 be revised into a fairly different proposal, one that introduces a new infix “&” type operator for representing protocol and other type compositions. Instead of:

  func f(a : protocol<A, B>) {}
  func g<T : A>(x : T) where T : B {} or func g<T : protocol<A, B>>(x : T) {}

You would instead write:

  func f(a : A & B) {}
  func g<T : A & B>(x : T) {}

The degenerate case of protocol<> needs an answer, but only for the definition of the Any typealias in the standard library, so it can be left out of the proposal.

The core team feels that this is an elegant solution for Swift 3 that conveys exactly the right intent. When generalized existentials are introduced, an elaborated syntax can be introduced to generalize this, e.g. "Any<A & B where … >” or “(T : A & B where …)” or whatever else makes sense in context of its design.

The principle concern with this is that having an “&" operator for generic constraints leads the question of whether the language should introduce an "|" operator to represent disjunctions in type constraints (something that the type system cannot and should not support). This is a topic that the C++ committee grappled with in its discussions of C++ concepts. That said, the core team feels that “&” directly expresses the relationship that we want, that “|” can be addressed in the “commonly rejected proposals" list, and that other proposals for an infix operator (like +) skirt this issue but are strictly worse at communicating intent in code.

Many thanks to Adrian Zubarev, Austin Zheng for driving this discussion!

-Chris Lattner
Review Manager


Proposal: Eliminate the Review phase
Cleaner way of writing functions for multiple types
(Austin Zheng) #2

This was indeed a very thorough review by the core team. I'll prepare a v2 proposal with this feedback taken into account so we can continue moving things along.

One quick question - is making whatever syntax is chosen for Swift 3 "forward-compatible" with a future generalized existential feature a concern?

Austin

···

On Jun 1, 2016, at 9:47 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0095-any-as-existential.md

Hello Swift Community,

The review of SE-0095: "Replace protocol<P1,P2> syntax with Any<P1,P2>" ran from May 24…30, 2016. The proposal is returned with revision requested - ideally the revised proposal will be included in Swift 3.

There was an incredible amount of feedback from the community, continuing even today. The principle problem identified by community about the proposal is that "Any<T1, T2>” implies very strongly an “any of T1 OR T2” relationship (aka disjunction) and not “any type conforming to T1 AND T2” relationship (aka conjunction). There was also some related discussion as to how the “Any<>” syntax aligns with future generalized existential syntax, much discussion as to whether it should be spelled Any<> or any<>, and some discussion about "angle bracket blindness".

The core team extensively discussed the feedback and considered many different possible paths forward. The conclusion of this is that it recommends that SE-0095 be revised into a fairly different proposal, one that introduces a new infix “&” type operator for representing protocol and other type compositions. Instead of:

  func f(a : protocol<A, B>) {}
  func g<T : A>(x : T) where T : B {} or func g<T : protocol<A, B>>(x : T) {}

You would instead write:

  func f(a : A & B) {}
  func g<T : A & B>(x : T) {}

The degenerate case of protocol<> needs an answer, but only for the definition of the Any typealias in the standard library, so it can be left out of the proposal.

The core team feels that this is an elegant solution for Swift 3 that conveys exactly the right intent. When generalized existentials are introduced, an elaborated syntax can be introduced to generalize this, e.g. "Any<A & B where … >” or “(T : A & B where …)” or whatever else makes sense in context of its design.

The principle concern with this is that having an “&" operator for generic constraints leads the question of whether the language should introduce an "|" operator to represent disjunctions in type constraints (something that the type system cannot and should not support). This is a topic that the C++ committee grappled with in its discussions of C++ concepts. That said, the core team feels that “&” directly expresses the relationship that we want, that “|” can be addressed in the “commonly rejected proposals" list, and that other proposals for an infix operator (like +) skirt this issue but are strictly worse at communicating intent in code.

Many thanks to Adrian Zubarev, Austin Zheng for driving this discussion!

-Chris Lattner
Review Manager
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(L Mihalkovic) #3

starting from this change, I tried to see how it could shape a possible generalized existential syntax. The grammar is not complete, but close enough to get a sense. It is also influenced by some recent changes regarding the status of ‘;’ versus ‘&’ versus ‘,’

https://gist.github.com/lmihalkovic/8aa66542f5cc4592e967bade260477ef

···

On Jun 2, 2016, at 6:47 AM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0095-any-as-existential.md

Hello Swift Community,

The review of SE-0095: "Replace protocol<P1,P2> syntax with Any<P1,P2>" ran from May 24…30, 2016. The proposal is returned with revision requested - ideally the revised proposal will be included in Swift 3.

There was an incredible amount of feedback from the community, continuing even today. The principle problem identified by community about the proposal is that "Any<T1, T2>” implies very strongly an “any of T1 OR T2” relationship (aka disjunction) and not “any type conforming to T1 AND T2” relationship (aka conjunction). There was also some related discussion as to how the “Any<>” syntax aligns with future generalized existential syntax, much discussion as to whether it should be spelled Any<> or any<>, and some discussion about "angle bracket blindness".

The core team extensively discussed the feedback and considered many different possible paths forward. The conclusion of this is that it recommends that SE-0095 be revised into a fairly different proposal, one that introduces a new infix “&” type operator for representing protocol and other type compositions. Instead of:

  func f(a : protocol<A, B>) {}
  func g<T : A>(x : T) where T : B {} or func g<T : protocol<A, B>>(x : T) {}

You would instead write:

  func f(a : A & B) {}
  func g<T : A & B>(x : T) {}

The degenerate case of protocol<> needs an answer, but only for the definition of the Any typealias in the standard library, so it can be left out of the proposal.

The core team feels that this is an elegant solution for Swift 3 that conveys exactly the right intent. When generalized existentials are introduced, an elaborated syntax can be introduced to generalize this, e.g. "Any<A & B where … >” or “(T : A & B where …)” or whatever else makes sense in context of its design.

The principle concern with this is that having an “&" operator for generic constraints leads the question of whether the language should introduce an "|" operator to represent disjunctions in type constraints (something that the type system cannot and should not support). This is a topic that the C++ committee grappled with in its discussions of C++ concepts. That said, the core team feels that “&” directly expresses the relationship that we want, that “|” can be addressed in the “commonly rejected proposals" list, and that other proposals for an infix operator (like +) skirt this issue but are strictly worse at communicating intent in code.

Many thanks to Adrian Zubarev, Austin Zheng for driving this discussion!

-Chris Lattner
Review Manager
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Chris Lattner) #4

Yes it is a concern, but we assume that the “X & Y” syntax will always be accepted going forward, as sugar for the more general feature that is yet to be designed.

-Chris

···

On Jun 1, 2016, at 9:53 PM, Austin Zheng <austinzheng@gmail.com> wrote:

This was indeed a very thorough review by the core team. I'll prepare a v2 proposal with this feedback taken into account so we can continue moving things along.

One quick question - is making whatever syntax is chosen for Swift 3 "forward-compatible" with a future generalized existential feature a concern?


(Austin Zheng) #5

Excellent.

I put together a PR with a revised proposal containing the core team's recommended approach. If anyone is curious they can see it here: https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md

Since this is the de-facto second round discussion thread, I'll start with my personal opinion (which is *not* reflected in the PR): the '&' separators in lieu of commas are a good idea, but I would still prefer the types to be wrapped in "Any<>", at least when being used as existentials.

My reasons:

- Jordan Rose brought up a good point in one of the discussion threads today: a resilience goal is to allow a library to add an associated type to a protocol that had none and not have it break user code. If this is true whatever syntax is used for existentials in Swift 3 should be a valid subset of the generalized existential syntax used to describe protocol compositions with no associated types.

- I would rather have "Any<>" be used consistently across all existential types eventually than have it only be used for (e.g.) existential types with `where` constraints, or allowing two different representations of the same existential type (one with Any, and one without).

- I think any generalized existential syntax without delimiting markers (like angle braces) is harder to read than syntax with such markers, so I would prefer a design with those markers.

Best,
Austin

···

On Jun 1, 2016, at 10:17 PM, Chris Lattner <clattner@apple.com> wrote:

On Jun 1, 2016, at 9:53 PM, Austin Zheng <austinzheng@gmail.com> wrote:

This was indeed a very thorough review by the core team. I'll prepare a v2 proposal with this feedback taken into account so we can continue moving things along.

One quick question - is making whatever syntax is chosen for Swift 3 "forward-compatible" with a future generalized existential feature a concern?

Yes it is a concern, but we assume that the “X & Y” syntax will always be accepted going forward, as sugar for the more general feature that is yet to be designed.

-Chris


(Xiaodi Wu) #6

Excellent.

I put together a PR with a revised proposal containing the core team's
recommended approach. If anyone is curious they can see it here:
https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md

Since this is the de-facto second round discussion thread, I'll start with
my personal opinion (which is *not* reflected in the PR): the '&'
separators in lieu of commas are a good idea, but I would still prefer the
types to be wrapped in "Any<>", at least when being used as existentials.

My reasons:

- Jordan Rose brought up a good point in one of the discussion threads
today: a resilience goal is to allow a library to add an associated type to
a protocol that had none and not have it break user code. If this is true
whatever syntax is used for existentials in Swift 3 should be a valid
subset of the generalized existential syntax used to describe protocol
compositions with no associated types.

- I would rather have "Any<>" be used consistently across all existential
types eventually than have it only be used for (e.g.) existential types
with `where` constraints, or allowing two different representations of the
same existential type (one with Any, and one without).

- I think any generalized existential syntax without delimiting markers
(like angle braces) is harder to read than syntax with such markers, so I
would prefer a design with those markers.

Agree with your reasons, but I'm still uncomfortable that things inside the
angle brackets would behave differently here than elsewhere. Would it help
to make a keyword out of `any` for existentials? Then you could have this:

func foo(value: any X & Y)

Best,

···

On Thu, Jun 2, 2016 at 12:42 AM, Austin Zheng via swift-evolution < swift-evolution@swift.org> wrote:

Austin

On Jun 1, 2016, at 10:17 PM, Chris Lattner <clattner@apple.com> wrote:

On Jun 1, 2016, at 9:53 PM, Austin Zheng <austinzheng@gmail.com> wrote:

This was indeed a very thorough review by the core team. I'll prepare a v2
proposal with this feedback taken into account so we can continue moving
things along.

One quick question - is making whatever syntax is chosen for Swift 3
"forward-compatible" with a future generalized existential feature a
concern?

Yes it is a concern, but we assume that the “X & Y” syntax will always be
accepted going forward, as sugar for the more general feature that is yet
to be designed.

-Chris

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Matthew Johnson) #7

Excellent.

I put together a PR with a revised proposal containing the core team's recommended approach. If anyone is curious they can see it here: https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md

Since this is the de-facto second round discussion thread, I'll start with my personal opinion (which is *not* reflected in the PR): the '&' separators in lieu of commas are a good idea, but I would still prefer the types to be wrapped in "Any<>", at least when being used as existentials.

Thanks for writing up the revision Austin, especially since it does not reflect your own opinion.

My opinion is that we should view these as type expressions. We don't require any kind of delimiters around value expressions, allowing optional parentheses for clarification and as a matter of style. I don't see any reason to treat type expressions any different than that syntactically.

···

Sent from my iPad

On Jun 2, 2016, at 12:42 AM, Austin Zheng via swift-evolution <swift-evolution@swift.org> wrote:

My reasons:

- Jordan Rose brought up a good point in one of the discussion threads today: a resilience goal is to allow a library to add an associated type to a protocol that had none and not have it break user code. If this is true whatever syntax is used for existentials in Swift 3 should be a valid subset of the generalized existential syntax used to describe protocol compositions with no associated types.

- I would rather have "Any<>" be used consistently across all existential types eventually than have it only be used for (e.g.) existential types with `where` constraints, or allowing two different representations of the same existential type (one with Any, and one without).

- I think any generalized existential syntax without delimiting markers (like angle braces) is harder to read than syntax with such markers, so I would prefer a design with those markers.

Best,
Austin

On Jun 1, 2016, at 10:17 PM, Chris Lattner <clattner@apple.com> wrote:

On Jun 1, 2016, at 9:53 PM, Austin Zheng <austinzheng@gmail.com> wrote:

This was indeed a very thorough review by the core team. I'll prepare a v2 proposal with this feedback taken into account so we can continue moving things along.

One quick question - is making whatever syntax is chosen for Swift 3 "forward-compatible" with a future generalized existential feature a concern?

Yes it is a concern, but we assume that the “X & Y” syntax will always be accepted going forward, as sugar for the more general feature that is yet to be designed.

-Chris

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Taras Zakharko) #8

I never had any problems with commas, as I always read them as conjunctive clauses, but I understand that an explicit conjunction may be less confusing. Personally, I’d prefer if there was no special syntax (aka Any<>) for existential types, whether generalised or not. I fail to see a principal difference between an existential type vardecl and a non-existential type vardecl: both can be described as sets of factual types, with non-existential declarations trivially being sets of cardinality one. Under this perspective, adopting different syntax for these cases feels like an idiosyncratic decision to me. I also disagree that Any<> makes existential types more readable, on contrary, they introduce visual clutter. A considerably complex existential definition could always be hidden behind a typealias.

Ideally, I’d like ALL type references in variable declarations be treated as existentials: the variable is declared as belonging to a certain set of factual types (in most cases this will trivially be a single factual type). IMO, this would result in a simple and concise system. It would also make type-erased wrappers unnecessary, simplifying the language.

Best,

Taras

···

On 02 Jun 2016, at 07:42, Austin Zheng via swift-evolution <swift-evolution@swift.org> wrote:

Excellent.

I put together a PR with a revised proposal containing the core team's recommended approach. If anyone is curious they can see it here: https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md

Since this is the de-facto second round discussion thread, I'll start with my personal opinion (which is *not* reflected in the PR): the '&' separators in lieu of commas are a good idea, but I would still prefer the types to be wrapped in "Any<>", at least when being used as existentials.

My reasons:

- Jordan Rose brought up a good point in one of the discussion threads today: a resilience goal is to allow a library to add an associated type to a protocol that had none and not have it break user code. If this is true whatever syntax is used for existentials in Swift 3 should be a valid subset of the generalized existential syntax used to describe protocol compositions with no associated types.

- I would rather have "Any<>" be used consistently across all existential types eventually than have it only be used for (e.g.) existential types with `where` constraints, or allowing two different representations of the same existential type (one with Any, and one without).

- I think any generalized existential syntax without delimiting markers (like angle braces) is harder to read than syntax with such markers, so I would prefer a design with those markers.

Best,
Austin

On Jun 1, 2016, at 10:17 PM, Chris Lattner <clattner@apple.com <mailto:clattner@apple.com>> wrote:

On Jun 1, 2016, at 9:53 PM, Austin Zheng <austinzheng@gmail.com <mailto:austinzheng@gmail.com>> wrote:

This was indeed a very thorough review by the core team. I'll prepare a v2 proposal with this feedback taken into account so we can continue moving things along.

One quick question - is making whatever syntax is chosen for Swift 3 "forward-compatible" with a future generalized existential feature a concern?

Yes it is a concern, but we assume that the “X & Y” syntax will always be accepted going forward, as sugar for the more general feature that is yet to be designed.

-Chris

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Thorsten Seitz) #9

Excellent.

I put together a PR with a revised proposal containing the core team's recommended approach. If anyone is curious they can see it here: https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md

Since this is the de-facto second round discussion thread, I'll start with my personal opinion (which is *not* reflected in the PR): the '&' separators in lieu of commas are a good idea, but I would still prefer the types to be wrapped in "Any<>", at least when being used as existentials.

I'm very happy with using `&` as I find this very readable.
I would prefer not having to wrap them into `Any<>`. While I can image `Any<>`, or rather `any<>`, for existentials with `where` clauses, I would absolutely hate having to wrap all existentials into that which would introduce a lot of noise.

My reasons:

- Jordan Rose brought up a good point in one of the discussion threads today: a resilience goal is to allow a library to add an associated type to a protocol that had none and not have it break user code. If this is true whatever syntax is used for existentials in Swift 3 should be a valid subset of the generalized existential syntax used to describe protocol compositions with no associated types.

If `P` is an existential there is no problem either, isn't it? No need to require `Any<P>`.

- I would rather have "Any<>" be used consistently across all existential types eventually than have it only be used for (e.g.) existential types with `where` constraints, or allowing two different representations of the same existential type (one with Any, and one without).

Far too much noise!

- I think any generalized existential syntax without delimiting markers (like angle braces) is harder to read than syntax with such markers, so I would prefer a design with those markers.

I think markers are only needed if a `where` clause is present and probably not even then.

-Thorsten

···

Am 02.06.2016 um 07:42 schrieb Austin Zheng via swift-evolution <swift-evolution@swift.org>:

Best,
Austin

On Jun 1, 2016, at 10:17 PM, Chris Lattner <clattner@apple.com> wrote:

On Jun 1, 2016, at 9:53 PM, Austin Zheng <austinzheng@gmail.com> wrote:

This was indeed a very thorough review by the core team. I'll prepare a v2 proposal with this feedback taken into account so we can continue moving things along.

One quick question - is making whatever syntax is chosen for Swift 3 "forward-compatible" with a future generalized existential feature a concern?

Yes it is a concern, but we assume that the “X & Y” syntax will always be accepted going forward, as sugar for the more general feature that is yet to be designed.

-Chris

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(L Mihalkovic) #10

I noticed that the "impacted" section was not updated to the new syntax. Additionally it might be useful to show the impact on the grammar.
Regards
(From mobile)

···

On Jun 2, 2016, at 7:42 AM, Austin Zheng via swift-evolution <swift-evolution@swift.org> wrote:

Excellent.

I put together a PR with a revised proposal containing the core team's recommended approach. If anyone is curious they can see it here: https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md

Since this is the de-facto second round discussion thread, I'll start with my personal opinion (which is *not* reflected in the PR): the '&' separators in lieu of commas are a good idea, but I would still prefer the types to be wrapped in "Any<>", at least when being used as existentials.

My reasons:

- Jordan Rose brought up a good point in one of the discussion threads today: a resilience goal is to allow a library to add an associated type to a protocol that had none and not have it break user code. If this is true whatever syntax is used for existentials in Swift 3 should be a valid subset of the generalized existential syntax used to describe protocol compositions with no associated types.

- I would rather have "Any<>" be used consistently across all existential types eventually than have it only be used for (e.g.) existential types with `where` constraints, or allowing two different representations of the same existential type (one with Any, and one without).

- I think any generalized existential syntax without delimiting markers (like angle braces) is harder to read than syntax with such markers, so I would prefer a design with those markers.

Best,
Austin

On Jun 1, 2016, at 10:17 PM, Chris Lattner <clattner@apple.com> wrote:

On Jun 1, 2016, at 9:53 PM, Austin Zheng <austinzheng@gmail.com> wrote:

This was indeed a very thorough review by the core team. I'll prepare a v2 proposal with this feedback taken into account so we can continue moving things along.

One quick question - is making whatever syntax is chosen for Swift 3 "forward-compatible" with a future generalized existential feature a concern?

Yes it is a concern, but we assume that the “X & Y” syntax will always be accepted going forward, as sugar for the more general feature that is yet to be designed.

-Chris

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Austin Zheng) #11

I definitely agree with your concern about angle brackets being used outside a generic context. However, I think I'd prefer the core team syntax (unadorned "P1 & P2") if delimiters are out of the question for now.

One option might be to use parentheses: Any(X & Y & Z), or square brackets: Any[X & Y & Z]. The former might look too much like a function call, although if we're going to call '&' a type infix operator we might as well stretch the analogy as far as it'll go. I actually like the second approach: you can't define static subscripts (and you wouldn't be able to define them on `Any` even if you could), so it wouldn't occupy an already-extant syntactic slot. Either would give existential types their own characteristic syntax, avoiding the angle brackets issue you brought up.

Austin

···

On Jun 1, 2016, at 11:39 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Thu, Jun 2, 2016 at 12:42 AM, Austin Zheng via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Excellent.

I put together a PR with a revised proposal containing the core team's recommended approach. If anyone is curious they can see it here: https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md

Since this is the de-facto second round discussion thread, I'll start with my personal opinion (which is *not* reflected in the PR): the '&' separators in lieu of commas are a good idea, but I would still prefer the types to be wrapped in "Any<>", at least when being used as existentials.

My reasons:

- Jordan Rose brought up a good point in one of the discussion threads today: a resilience goal is to allow a library to add an associated type to a protocol that had none and not have it break user code. If this is true whatever syntax is used for existentials in Swift 3 should be a valid subset of the generalized existential syntax used to describe protocol compositions with no associated types.

- I would rather have "Any<>" be used consistently across all existential types eventually than have it only be used for (e.g.) existential types with `where` constraints, or allowing two different representations of the same existential type (one with Any, and one without).

- I think any generalized existential syntax without delimiting markers (like angle braces) is harder to read than syntax with such markers, so I would prefer a design with those markers.

Agree with your reasons, but I'm still uncomfortable that things inside the angle brackets would behave differently here than elsewhere. Would it help to make a keyword out of `any` for existentials? Then you could have this:

func foo(value: any X & Y)

Best,
Austin

On Jun 1, 2016, at 10:17 PM, Chris Lattner <clattner@apple.com <mailto:clattner@apple.com>> wrote:

On Jun 1, 2016, at 9:53 PM, Austin Zheng <austinzheng@gmail.com <mailto:austinzheng@gmail.com>> wrote:

This was indeed a very thorough review by the core team. I'll prepare a v2 proposal with this feedback taken into account so we can continue moving things along.

One quick question - is making whatever syntax is chosen for Swift 3 "forward-compatible" with a future generalized existential feature a concern?

Yes it is a concern, but we assume that the “X & Y” syntax will always be accepted going forward, as sugar for the more general feature that is yet to be designed.

-Chris

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Austin Zheng) #12

I'm sure the list is getting sick of me making this point over and
over again :), so I'll only do it one more time: I find the lack of
delimiters far worse in terms of readability for type expressions of
any appreciable complexity than any number of `Any<>` tokens. In fact,
I'm a bit surprised the core team decided to go in this direction,
given their stance on parentheses for function types, and replacing
operators like "&&" or "||" with "and" or "or". I respect their
decision, though.

···

On 6/2/16, Thorsten Seitz <tseitz42@icloud.com> wrote:

Am 02.06.2016 um 07:42 schrieb Austin Zheng via swift-evolution >> <swift-evolution@swift.org>:

Excellent.

I put together a PR with a revised proposal containing the core team's
recommended approach. If anyone is curious they can see it here:
https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md

Since this is the de-facto second round discussion thread, I'll start with
my personal opinion (which is *not* reflected in the PR): the '&'
separators in lieu of commas are a good idea, but I would still prefer the
types to be wrapped in "Any<>", at least when being used as existentials.

I'm very happy with using `&` as I find this very readable.
I would prefer not having to wrap them into `Any<>`. While I can image
`Any<>`, or rather `any<>`, for existentials with `where` clauses, I would
absolutely hate having to wrap all existentials into that which would
introduce a lot of noise.

My reasons:

- Jordan Rose brought up a good point in one of the discussion threads
today: a resilience goal is to allow a library to add an associated type
to a protocol that had none and not have it break user code. If this is
true whatever syntax is used for existentials in Swift 3 should be a valid
subset of the generalized existential syntax used to describe protocol
compositions with no associated types.

If `P` is an existential there is no problem either, isn't it? No need to
require `Any<P>`.

- I would rather have "Any<>" be used consistently across all existential
types eventually than have it only be used for (e.g.) existential types
with `where` constraints, or allowing two different representations of the
same existential type (one with Any, and one without).

Far too much noise!

- I think any generalized existential syntax without delimiting markers
(like angle braces) is harder to read than syntax with such markers, so I
would prefer a design with those markers.

I think markers are only needed if a `where` clause is present and probably
not even then.

-Thorsten

Best,
Austin

On Jun 1, 2016, at 10:17 PM, Chris Lattner <clattner@apple.com> wrote:

On Jun 1, 2016, at 9:53 PM, Austin Zheng <austinzheng@gmail.com> wrote:

This was indeed a very thorough review by the core team. I'll prepare a
v2 proposal with this feedback taken into account so we can continue
moving things along.

One quick question - is making whatever syntax is chosen for Swift 3
"forward-compatible" with a future generalized existential feature a
concern?

Yes it is a concern, but we assume that the “X & Y” syntax will always be
accepted going forward, as sugar for the more general feature that is yet
to be designed.

-Chris

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Matthew Johnson) #13

Excellent.

I put together a PR with a revised proposal containing the core team's recommended approach. If anyone is curious they can see it here: https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md

Since this is the de-facto second round discussion thread, I'll start with my personal opinion (which is *not* reflected in the PR): the '&' separators in lieu of commas are a good idea, but I would still prefer the types to be wrapped in "Any<>", at least when being used as existentials.

I'm very happy with using `&` as I find this very readable.
I would prefer not having to wrap them into `Any<>`. While I can image `Any<>`, or rather `any<>`, for existentials with `where` clauses, I would absolutely hate having to wrap all existentials into that which would introduce a lot of noise.

My reasons:

- Jordan Rose brought up a good point in one of the discussion threads today: a resilience goal is to allow a library to add an associated type to a protocol that had none and not have it break user code. If this is true whatever syntax is used for existentials in Swift 3 should be a valid subset of the generalized existential syntax used to describe protocol compositions with no associated types.

If `P` is an existential there is no problem either, isn't it? No need to require `Any<P>`.

- I would rather have "Any<>" be used consistently across all existential types eventually than have it only be used for (e.g.) existential types with `where` constraints, or allowing two different representations of the same existential type (one with Any, and one without).

Far too much noise!

- I think any generalized existential syntax without delimiting markers (like angle braces) is harder to read than syntax with such markers, so I would prefer a design with those markers.

I think markers are only needed if a `where` clause is present and probably not even then.

The only reason to require them generally is if they are required for disambiguation in specific syntactic positions and it would be too confusing to remember where parentheses are required. If that isn’t the case they should not be required. It would be interesting to hear from someone closer to the grammar about whether an enclosing syntactic context would ever be required for disambiguation or not.

If we don’t require them, parentheses can still be used for clarity when desired.

···

On Jun 2, 2016, at 10:14 AM, Thorsten Seitz via swift-evolution <swift-evolution@swift.org> wrote:
Am 02.06.2016 um 07:42 schrieb Austin Zheng via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

-Thorsten

Best,
Austin

On Jun 1, 2016, at 10:17 PM, Chris Lattner <clattner@apple.com <mailto:clattner@apple.com>> wrote:

On Jun 1, 2016, at 9:53 PM, Austin Zheng <austinzheng@gmail.com <mailto:austinzheng@gmail.com>> wrote:

This was indeed a very thorough review by the core team. I'll prepare a v2 proposal with this feedback taken into account so we can continue moving things along.

One quick question - is making whatever syntax is chosen for Swift 3 "forward-compatible" with a future generalized existential feature a concern?

Yes it is a concern, but we assume that the “X & Y” syntax will always be accepted going forward, as sugar for the more general feature that is yet to be designed.

-Chris

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Adrian Zubarev) #14

I like the decision of the core team to replace protocol<…> with something like & instead. This gives us room to rethink Any<…> or come up with even better mechanism for existentials. :slight_smile:

There are still a few things to consider:

AnyObject and AnyClass:
I’d prefer to drop the current AnyClass and rename AnyObject to AnyClass, where the current AnyClass would be used as AnyClass.Type.
AnyClass & SomeProtocol looks better to me than AnyObject & SomeProtocol.
What do you think?
Would nesting for class-requirement work the same as we described before?

···

--
Adrian Zubarev
Sent with Airmail

Am 2. Juni 2016 um 17:25:54, Austin Zheng via swift-evolution (swift-evolution@swift.org) schrieb:

I'm sure the list is getting sick of me making this point over and
over again :), so I'll only do it one more time: I find the lack of
delimiters far worse in terms of readability for type expressions of
any appreciable complexity than any number of `Any<>` tokens. In fact,
I'm a bit surprised the core team decided to go in this direction,
given their stance on parentheses for function types, and replacing
operators like "&&" or "||" with "and" or "or". I respect their
decision, though.

On 6/2/16, Thorsten Seitz <tseitz42@icloud.com> wrote:

Am 02.06.2016 um 07:42 schrieb Austin Zheng via swift-evolution >> <swift-evolution@swift.org>:

Excellent.

I put together a PR with a revised proposal containing the core team's
recommended approach. If anyone is curious they can see it here:
https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md

Since this is the de-facto second round discussion thread, I'll start with
my personal opinion (which is *not* reflected in the PR): the '&'
separators in lieu of commas are a good idea, but I would still prefer the
types to be wrapped in "Any<>", at least when being used as existentials.

I'm very happy with using `&` as I find this very readable.
I would prefer not having to wrap them into `Any<>`. While I can image
`Any<>`, or rather `any<>`, for existentials with `where` clauses, I would
absolutely hate having to wrap all existentials into that which would
introduce a lot of noise.

My reasons:

- Jordan Rose brought up a good point in one of the discussion threads
today: a resilience goal is to allow a library to add an associated type
to a protocol that had none and not have it break user code. If this is
true whatever syntax is used for existentials in Swift 3 should be a valid
subset of the generalized existential syntax used to describe protocol
compositions with no associated types.

If `P` is an existential there is no problem either, isn't it? No need to
require `Any<P>`.

- I would rather have "Any<>" be used consistently across all existential
types eventually than have it only be used for (e.g.) existential types
with `where` constraints, or allowing two different representations of the
same existential type (one with Any, and one without).

Far too much noise!

- I think any generalized existential syntax without delimiting markers
(like angle braces) is harder to read than syntax with such markers, so I
would prefer a design with those markers.

I think markers are only needed if a `where` clause is present and probably
not even then.

-Thorsten

Best,
Austin

On Jun 1, 2016, at 10:17 PM, Chris Lattner <clattner@apple.com> wrote:

On Jun 1, 2016, at 9:53 PM, Austin Zheng <austinzheng@gmail.com> wrote:

This was indeed a very thorough review by the core team. I'll prepare a
v2 proposal with this feedback taken into account so we can continue
moving things along.

One quick question - is making whatever syntax is chosen for Swift 3
"forward-compatible" with a future generalized existential feature a
concern?

Yes it is a concern, but we assume that the “X & Y” syntax will always be
accepted going forward, as sugar for the more general feature that is yet
to be designed.

-Chris

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jordan Rose) #15

Yep. I also remain against this syntax, primarily for reasons of learnability.

···

On Jun 2, 2016, at 08:25, Austin Zheng via swift-evolution <swift-evolution@swift.org> wrote:

I'm sure the list is getting sick of me making this point over and
over again :), so I'll only do it one more time: I find the lack of
delimiters far worse in terms of readability for type expressions of
any appreciable complexity than any number of `Any<>` tokens. In fact,
I'm a bit surprised the core team decided to go in this direction,
given their stance on parentheses for function types, and replacing
operators like "&&" or "||" with "and" or "or". I respect their
decision, though.

On 6/2/16, Thorsten Seitz <tseitz42@icloud.com> wrote:

Am 02.06.2016 um 07:42 schrieb Austin Zheng via swift-evolution >>> <swift-evolution@swift.org>:

Excellent.

I put together a PR with a revised proposal containing the core team's
recommended approach. If anyone is curious they can see it here:
https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md

Since this is the de-facto second round discussion thread, I'll start with
my personal opinion (which is *not* reflected in the PR): the '&'
separators in lieu of commas are a good idea, but I would still prefer the
types to be wrapped in "Any<>", at least when being used as existentials.

I'm very happy with using `&` as I find this very readable.
I would prefer not having to wrap them into `Any<>`. While I can image
`Any<>`, or rather `any<>`, for existentials with `where` clauses, I would
absolutely hate having to wrap all existentials into that which would
introduce a lot of noise.

My reasons:

- Jordan Rose brought up a good point in one of the discussion threads
today: a resilience goal is to allow a library to add an associated type
to a protocol that had none and not have it break user code. If this is
true whatever syntax is used for existentials in Swift 3 should be a valid
subset of the generalized existential syntax used to describe protocol
compositions with no associated types.

If `P` is an existential there is no problem either, isn't it? No need to
require `Any<P>`.

- I would rather have "Any<>" be used consistently across all existential
types eventually than have it only be used for (e.g.) existential types
with `where` constraints, or allowing two different representations of the
same existential type (one with Any, and one without).

Far too much noise!

- I think any generalized existential syntax without delimiting markers
(like angle braces) is harder to read than syntax with such markers, so I
would prefer a design with those markers.

I think markers are only needed if a `where` clause is present and probably
not even then.

-Thorsten

Best,
Austin

On Jun 1, 2016, at 10:17 PM, Chris Lattner <clattner@apple.com> wrote:

On Jun 1, 2016, at 9:53 PM, Austin Zheng <austinzheng@gmail.com> wrote:

This was indeed a very thorough review by the core team. I'll prepare a
v2 proposal with this feedback taken into account so we can continue
moving things along.

One quick question - is making whatever syntax is chosen for Swift 3
"forward-compatible" with a future generalized existential feature a
concern?

Yes it is a concern, but we assume that the “X & Y” syntax will always be
accepted going forward, as sugar for the more general feature that is yet
to be designed.

-Chris

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(L Mihalkovic) #16

I noticed that the "impacted" section was not updated to the new syntax.

apologies, I was looking at the last reference to Any, and it is indeed correct as it is.

as for the grammar, I guess it is just a matter of removing the reference to protocol<> and swapping in the new & operator in composition types:
GRAMMAR OF A PROTOCOL COMPOSITION TYPE

<>protocol-composition-type → protocol­<­protocol-identifier-list <https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Types.html#//apple_ref/swift/grammar/protocol-identifier-list>­opt­>­
<>protocol-identifier-list → protocol-identifier <https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Types.html#//apple_ref/swift/grammar/protocol-identifier>­ protocol-identifier <https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Types.html#//apple_ref/swift/grammar/protocol-identifier>­,­protocol-identifier-list <https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Types.html#//apple_ref/swift/grammar/protocol-identifier-list
<>protocol-identifier → type-identifier <https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Types.html#//apple_ref/swift/grammar/type-identifier
GRAMMAR OF A PROTOCOL COMPOSITION TYPE

<>protocol-composition-type → protocol-identifier-list <https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Types.html#//apple_ref/swift/grammar/protocol-identifier-list
<>protocol-identifier-list → protocol-identifier <https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Types.html#//apple_ref/swift/grammar/protocol-identifier>­ protocol-identifier <https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Types.html#//apple_ref/swift/grammar/protocol-identifier>­&­protocol-identifier-list <https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Types.html#//apple_ref/swift/grammar/protocol-identifier-list
<>protocol-identifier → type-identifier <https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Types.html#//apple_ref/swift/grammar/type-identifier
In this form there is the problem of the degenerate case where protocol-identifier-list is empty which is required for Any. The syntax I have been playing with for generalized existential would degenerate fine for covering this gap.

https://gist.github.com/lmihalkovic/8aa66542f5cc4592e967bade260477ef

···

On Jun 10, 2016, at 4:20 PM, L. Mihalkovic <laurent.mihalkovic@gmail.com> wrote:

Additionally it might be useful to show the impact on the grammar.
Regards
(From mobile)
On Jun 2, 2016, at 7:42 AM, Austin Zheng via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Excellent.

I put together a PR with a revised proposal containing the core team's recommended approach. If anyone is curious they can see it here: https://github.com/austinzheng/swift-evolution/blob/ef6adbe0fe09bff6c44c6aa9d73ee407629235ce/proposals/0095-any-as-existential.md

Since this is the de-facto second round discussion thread, I'll start with my personal opinion (which is *not* reflected in the PR): the '&' separators in lieu of commas are a good idea, but I would still prefer the types to be wrapped in "Any<>", at least when being used as existentials.

My reasons:

- Jordan Rose brought up a good point in one of the discussion threads today: a resilience goal is to allow a library to add an associated type to a protocol that had none and not have it break user code. If this is true whatever syntax is used for existentials in Swift 3 should be a valid subset of the generalized existential syntax used to describe protocol compositions with no associated types.

- I would rather have "Any<>" be used consistently across all existential types eventually than have it only be used for (e.g.) existential types with `where` constraints, or allowing two different representations of the same existential type (one with Any, and one without).

- I think any generalized existential syntax without delimiting markers (like angle braces) is harder to read than syntax with such markers, so I would prefer a design with those markers.

Best,
Austin

On Jun 1, 2016, at 10:17 PM, Chris Lattner <clattner@apple.com <mailto:clattner@apple.com>> wrote:

On Jun 1, 2016, at 9:53 PM, Austin Zheng <austinzheng@gmail.com <mailto:austinzheng@gmail.com>> wrote:

This was indeed a very thorough review by the core team. I'll prepare a v2 proposal with this feedback taken into account so we can continue moving things along.

One quick question - is making whatever syntax is chosen for Swift 3 "forward-compatible" with a future generalized existential feature a concern?

Yes it is a concern, but we assume that the “X & Y” syntax will always be accepted going forward, as sugar for the more general feature that is yet to be designed.

-Chris

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution