Typealiases in protocols and protocol extensions


(David Hart) #1

Hello,

I’ve come again with another proposal directly from the Generics Manifesto. Please let me know if it needs any modifications before sending the pull request.

Typealiases in protocols and protocol extensions

Proposal: SE-XXXX <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
Authors: David Hart <https://github.com/hartbit>, Doug Gregor <https://github.com/DougGregor>
Status: TBD
Review manager: TBD
<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>Introduction

This proposal is from the Generics Manifesto <https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside of protocols to declare type aliases and in protocols to declare associated types. Since SE-0011 <https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and Swift 2.2, associated type now use the associatedtype keyword and typelias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed solution

The solution allows the creation of associated type aliases. Here is an example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}
The example above shows how this simplifies referencing indirect associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}
<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed design

The following grammar rules needs to be added:

protocol-member-declaration → protocol-typealias-declaration

protocol-typealias-declaration → typealias-declaration

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact on existing code

This will have no impact on existing code, but will probably require improving the Fix-It that was created for migrating typealias to associatedtype in Swift 2.2.


(Xiaodi Wu) #2

If the protocol Sequence has typealias Element, does that mean I also have
MyConformingSequence.Element?

If so, I think there is a potential impact on existing code not mentioned.
Suppose MyConformingSequence already (unwisely) declares typealias Element.
Now, what happens when I try to migrate my code to your proposed version of
Swift?

This is a toy example, of course. More generally, though, I wonder about
this question:

Suppose two protocols A and B each declare typealias Element. These
typealiases are, as you proposed, intended to simplify referencing indirect
associated types. But are they themselves considered protocol requirements?

I ask because, suppose I want to conform type T to A and B. I implement all
the required methods and properties for such conformance. I declare the
appropriate typealiases for the associatedtypes declared in both protocols.
But, if A.Element and B.Element are incompatible with each other, it is
nonetheless impossible to conform T to both A and B? If it's forbidden,
isn't that kind of a bummer, since what's getting in the way is a naming
clash arising from a facility intended to simplify the naming of things
rather than provide for new functionality? If it's permitted, what is
T.Element? Some clarity here would be nice.

···

On Sun, May 8, 2016 at 6:17 PM David Hart via swift-evolution < swift-evolution@swift.org> wrote:

Hello,

I’ve come again with another proposal directly from the Generics
Manifesto. Please let me know if it needs any modifications before sending
the pull request.

Typealiases in protocols and protocol extensions

   - Proposal: SE-XXXX
   <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
   - Authors: David Hart <https://github.com/hartbit>, Doug Gregor
   <https://github.com/DougGregor>
   - Status: TBD
   - Review manager: TBD

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>
Introduction

This proposal is from the Generics Manifesto
<https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and
brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>
Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside of
protocols to declare type aliases and in protocols to declare associated
types. Since SE-0011
<https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and
Swift 2.2, associated type now use the associatedtype keyword and typelias is
available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed
solution

The solution allows the creation of associated type aliases. Here is an
example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}

The example above shows how this simplifies referencing indirect
associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed
design

The following grammar rules needs to be added:

*protocol-member-declaration* → *protocol-typealias-declaration*

*protocol-typealias-declaration* → *typealias-declaration*

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact
on existing code
This will have no impact on existing code, but will probably require
improving the Fix-It that was created for migrating typealias to
associatedtype in Swift 2.2.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(David Hart) #3

Hello Xiaodi,

What I mean by there is no impact on existing code is that the language change has no impact. Of course, if the Standard Library then declares a typealias Element in Sequence, it will clash with code which has declared an Element typealias in sub-protocols, but that is separate from the proposal.

···

On 09 May 2016, at 07:28, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

If the protocol Sequence has typealias Element, does that mean I also have MyConformingSequence.Element?

If so, I think there is a potential impact on existing code not mentioned. Suppose MyConformingSequence already (unwisely) declares typealias Element. Now, what happens when I try to migrate my code to your proposed version of Swift?

This is a toy example, of course. More generally, though, I wonder about this question:

Suppose two protocols A and B each declare typealias Element. These typealiases are, as you proposed, intended to simplify referencing indirect associated types. But are they themselves considered protocol requirements?

I ask because, suppose I want to conform type T to A and B. I implement all the required methods and properties for such conformance. I declare the appropriate typealiases for the associatedtypes declared in both protocols. But, if A.Element and B.Element are incompatible with each other, it is nonetheless impossible to conform T to both A and B? If it's forbidden, isn't that kind of a bummer, since what's getting in the way is a naming clash arising from a facility intended to simplify the naming of things rather than provide for new functionality? If it's permitted, what is T.Element? Some clarity here would be nice.
On Sun, May 8, 2016 at 6:17 PM David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hello,

I’ve come again with another proposal directly from the Generics Manifesto. Please let me know if it needs any modifications before sending the pull request.

Typealiases in protocols and protocol extensions

Proposal: SE-XXXX <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
Authors: David Hart <https://github.com/hartbit>, Doug Gregor <https://github.com/DougGregor>
Status: TBD
Review manager: TBD
<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>Introduction

This proposal is from the Generics Manifesto <https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside of protocols to declare type aliases and in protocols to declare associated types. Since SE-0011 <https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and Swift 2.2, associated type now use the associatedtype keyword and typelias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed solution

The solution allows the creation of associated type aliases. Here is an example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}
The example above shows how this simplifies referencing indirect associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}
<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed design

The following grammar rules needs to be added:

protocol-member-declaration → protocol-typealias-declaration

protocol-typealias-declaration → typealias-declaration

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact on existing code

This will have no impact on existing code, but will probably require improving the Fix-It that was created for migrating typealias to associatedtype in Swift 2.2.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Xiaodi Wu) #4

I see your point that nothing breaks in the stdlib with your proposal
alone. It's undeniably true--by construction!--that a purely additive
feature, if never used, will not cause problems.

That said, since the time that this feature was outlined in Doug's
manifesto, I have been wondering how clashes such as the examples in my
previous email are to be handled--i.e. what the rules of the language are
to be--which I think is certainly germane to your proposal. Can a
conforming type override a protocol typealias? Can a type conform to two
protocols with conflicting typealiases if all requirements are otherwise
satisfied? Surely, these merit discussion in your proposal.

···

On Mon, May 9, 2016 at 12:48 AM David Hart <david@hartbit.com> wrote:

Hello Xiaodi,

What I mean by there is no impact on existing code is that the language
change has no impact. Of course, if the Standard Library then declares a
typealias Element in Sequence, it will clash with code which has declared
an Element typealias in sub-protocols, but that is separate from the
proposal.

On 09 May 2016, at 07:28, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

If the protocol Sequence has typealias Element, does that mean I also have
MyConformingSequence.Element?

If so, I think there is a potential impact on existing code not mentioned.
Suppose MyConformingSequence already (unwisely) declares typealias Element.
Now, what happens when I try to migrate my code to your proposed version of
Swift?

This is a toy example, of course. More generally, though, I wonder about
this question:

Suppose two protocols A and B each declare typealias Element. These
typealiases are, as you proposed, intended to simplify referencing indirect
associated types. But are they themselves considered protocol requirements?

I ask because, suppose I want to conform type T to A and B. I implement
all the required methods and properties for such conformance. I declare the
appropriate typealiases for the associatedtypes declared in both protocols.
But, if A.Element and B.Element are incompatible with each other, it is
nonetheless impossible to conform T to both A and B? If it's forbidden,
isn't that kind of a bummer, since what's getting in the way is a naming
clash arising from a facility intended to simplify the naming of things
rather than provide for new functionality? If it's permitted, what is
T.Element? Some clarity here would be nice.
On Sun, May 8, 2016 at 6:17 PM David Hart via swift-evolution < > swift-evolution@swift.org> wrote:

Hello,

I’ve come again with another proposal directly from the Generics
Manifesto. Please let me know if it needs any modifications before sending
the pull request.

Typealiases in protocols and protocol extensions

   - Proposal: SE-XXXX
   <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
   - Authors: David Hart <https://github.com/hartbit>, Doug Gregor
   <https://github.com/DougGregor>
   - Status: TBD
   - Review manager: TBD

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>
Introduction

This proposal is from the Generics Manifesto
<https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and
brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>
Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside of
protocols to declare type aliases and in protocols to declare associated
types. Since SE-0011
<https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and
Swift 2.2, associated type now use the associatedtype keyword and
typelias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed
solution

The solution allows the creation of associated type aliases. Here is an
example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}

The example above shows how this simplifies referencing indirect
associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed
design

The following grammar rules needs to be added:

*protocol-member-declaration* → *protocol-typealias-declaration*

*protocol-typealias-declaration* → *typealias-declaration*

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact
on existing code
This will have no impact on existing code, but will probably require
improving the Fix-It that was created for migrating typealias to
associatedtype in Swift 2.2.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Xiaodi Wu) #5

And to clarify, FWIW, I think it'd be wonderful to implement this feature,
and I share your sense that sometimes conversations on this list get a
little sidetracked. My comments are not meant to suggest that this is not a
good feature; rather, they go to your question to the list--does your
proposal need any modifications before a PR?

IMO, some sections need to be fleshed out. Some discussion on how your
proposed rules interact with other aspects of the language when they are
used in the daily task of conforming types to protocols is called for. I
accept your point that perhaps it doesn't belong in the 'Impact on Existing
Code' section.

I hope you'll forgive me for saying that the proposal seems, overall,
hastily written. That there are two misspelled instances of "typealias" in
a proposal about typealias does not give one confidence that what is
proposed has been sufficiently considered.

···

On Mon, May 9, 2016 at 01:06 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

I see your point that nothing breaks in the stdlib with your proposal
alone. It's undeniably true--by construction!--that a purely additive
feature, if never used, will not cause problems.

That said, since the time that this feature was outlined in Doug's
manifesto, I have been wondering how clashes such as the examples in my
previous email are to be handled--i.e. what the rules of the language are
to be--which I think is certainly germane to your proposal. Can a
conforming type override a protocol typealias? Can a type conform to two
protocols with conflicting typealiases if all requirements are otherwise
satisfied? Surely, these merit discussion in your proposal.

On Mon, May 9, 2016 at 12:48 AM David Hart <david@hartbit.com> wrote:

Hello Xiaodi,

What I mean by there is no impact on existing code is that the language
change has no impact. Of course, if the Standard Library then declares a
typealias Element in Sequence, it will clash with code which has declared
an Element typealias in sub-protocols, but that is separate from the
proposal.

On 09 May 2016, at 07:28, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

If the protocol Sequence has typealias Element, does that mean I also
have MyConformingSequence.Element?

If so, I think there is a potential impact on existing code not
mentioned. Suppose MyConformingSequence already (unwisely) declares
typealias Element. Now, what happens when I try to migrate my code to your
proposed version of Swift?

This is a toy example, of course. More generally, though, I wonder about
this question:

Suppose two protocols A and B each declare typealias Element. These
typealiases are, as you proposed, intended to simplify referencing indirect
associated types. But are they themselves considered protocol requirements?

I ask because, suppose I want to conform type T to A and B. I implement
all the required methods and properties for such conformance. I declare the
appropriate typealiases for the associatedtypes declared in both protocols.
But, if A.Element and B.Element are incompatible with each other, it is
nonetheless impossible to conform T to both A and B? If it's forbidden,
isn't that kind of a bummer, since what's getting in the way is a naming
clash arising from a facility intended to simplify the naming of things
rather than provide for new functionality? If it's permitted, what is
T.Element? Some clarity here would be nice.
On Sun, May 8, 2016 at 6:17 PM David Hart via swift-evolution < >> swift-evolution@swift.org> wrote:

Hello,

I’ve come again with another proposal directly from the Generics
Manifesto. Please let me know if it needs any modifications before sending
the pull request.

Typealiases in protocols and protocol extensions

   - Proposal: SE-XXXX
   <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
   - Authors: David Hart <https://github.com/hartbit>, Doug Gregor
   <https://github.com/DougGregor>
   - Status: TBD
   - Review manager: TBD

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>
Introduction

This proposal is from the Generics Manifesto
<https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and
brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>
Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside
of protocols to declare type aliases and in protocols to declare associated
types. Since SE-0011
<https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and
Swift 2.2, associated type now use the associatedtype keyword and
typelias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed
solution

The solution allows the creation of associated type aliases. Here is an
example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}

The example above shows how this simplifies referencing indirect
associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed
design

The following grammar rules needs to be added:

*protocol-member-declaration* → *protocol-typealias-declaration*

*protocol-typealias-declaration* → *typealias-declaration*

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact
on existing code
This will have no impact on existing code, but will probably require
improving the Fix-It that was created for migrating typealias to
associatedtype in Swift 2.2.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(David Hart) #6

I understand that name clashing in those instances is important to discuss, but I still think it is slightly orthogonal to the proposal. Let me try to explain why.

If typealises in protocols are to have the same semantics as alises outside protocols (as I think they should), then they don’t change anything about the rules of collision. For example, the problem already exists today with associated types:

protocol Foo {
    associatedtype Inner: IntegerType
    func foo(inner: Inner)
}

protocol Bar {
    associatedtype Inner: FloatingPointType
    var inner: Inner { get }
}

struct FooBarImpl: Foo, Bar { // error: Type ‘FooBarImpl’ does not conform to protocol ‘Bar'
    func foo(inner: Int) {}
    var inner: Float
}

Type aliasing would not change anything about the fact that those collisions already exists in the language and are not very well handled: either they are meant to be forbidden but in that case we need better diagnostics, or we want to have a way to work around them. Perhaps you’d like to start a discussion around fixing that ?

···

On 09 May 2016, at 08:06, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

I see your point that nothing breaks in the stdlib with your proposal alone. It's undeniably true--by construction!--that a purely additive feature, if never used, will not cause problems.

That said, since the time that this feature was outlined in Doug's manifesto, I have been wondering how clashes such as the examples in my previous email are to be handled--i.e. what the rules of the language are to be--which I think is certainly germane to your proposal. Can a conforming type override a protocol typealias? Can a type conform to two protocols with conflicting typealiases if all requirements are otherwise satisfied? Surely, these merit discussion in your proposal.

On Mon, May 9, 2016 at 12:48 AM David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:
Hello Xiaodi,

What I mean by there is no impact on existing code is that the language change has no impact. Of course, if the Standard Library then declares a typealias Element in Sequence, it will clash with code which has declared an Element typealias in sub-protocols, but that is separate from the proposal.

On 09 May 2016, at 07:28, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

If the protocol Sequence has typealias Element, does that mean I also have MyConformingSequence.Element?

If so, I think there is a potential impact on existing code not mentioned. Suppose MyConformingSequence already (unwisely) declares typealias Element. Now, what happens when I try to migrate my code to your proposed version of Swift?

This is a toy example, of course. More generally, though, I wonder about this question:

Suppose two protocols A and B each declare typealias Element. These typealiases are, as you proposed, intended to simplify referencing indirect associated types. But are they themselves considered protocol requirements?

I ask because, suppose I want to conform type T to A and B. I implement all the required methods and properties for such conformance. I declare the appropriate typealiases for the associatedtypes declared in both protocols. But, if A.Element and B.Element are incompatible with each other, it is nonetheless impossible to conform T to both A and B? If it's forbidden, isn't that kind of a bummer, since what's getting in the way is a naming clash arising from a facility intended to simplify the naming of things rather than provide for new functionality? If it's permitted, what is T.Element? Some clarity here would be nice.
On Sun, May 8, 2016 at 6:17 PM David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hello,

I’ve come again with another proposal directly from the Generics Manifesto. Please let me know if it needs any modifications before sending the pull request.

Typealiases in protocols and protocol extensions

Proposal: SE-XXXX <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
Authors: David Hart <https://github.com/hartbit>, Doug Gregor <https://github.com/DougGregor>
Status: TBD
Review manager: TBD
<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>Introduction

This proposal is from the Generics Manifesto <https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside of protocols to declare type aliases and in protocols to declare associated types. Since SE-0011 <https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and Swift 2.2, associated type now use the associatedtype keyword and typelias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed solution

The solution allows the creation of associated type aliases. Here is an example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}
The example above shows how this simplifies referencing indirect associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}
<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed design

The following grammar rules needs to be added:

protocol-member-declaration → protocol-typealias-declaration

protocol-typealias-declaration → typealias-declaration

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact on existing code

This will have no impact on existing code, but will probably require improving the Fix-It that was created for migrating typealias to associatedtype in Swift 2.2.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(David Hart) #7

And to clarify, FWIW, I think it'd be wonderful to implement this feature, and I share your sense that sometimes conversations on this list get a little sidetracked. My comments are not meant to suggest that this is not a good feature; rather, they go to your question to the list--does your proposal need any modifications before a PR?

IMO, some sections need to be fleshed out. Some discussion on how your proposed rules interact with other aspects of the language when they are used in the daily task of conforming types to protocols is called for. I accept your point that perhaps it doesn't belong in the 'Impact on Existing Code' section.

I’ll add something.

I hope you'll forgive me for saying that the proposal seems, overall, hastily written. That there are two misspelled instances of "typealias" in a proposal about typealias does not give one confidence that what is proposed has been sufficiently considered.

I don’t mind you saying it, it is a very early draft. That’s why I’m putting it in front of the community before sending it for a Pull Request.

···

On 09 May 2016, at 08:53, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, May 9, 2016 at 01:06 Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
I see your point that nothing breaks in the stdlib with your proposal alone. It's undeniably true--by construction!--that a purely additive feature, if never used, will not cause problems.

That said, since the time that this feature was outlined in Doug's manifesto, I have been wondering how clashes such as the examples in my previous email are to be handled--i.e. what the rules of the language are to be--which I think is certainly germane to your proposal. Can a conforming type override a protocol typealias? Can a type conform to two protocols with conflicting typealiases if all requirements are otherwise satisfied? Surely, these merit discussion in your proposal.

On Mon, May 9, 2016 at 12:48 AM David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:
Hello Xiaodi,

What I mean by there is no impact on existing code is that the language change has no impact. Of course, if the Standard Library then declares a typealias Element in Sequence, it will clash with code which has declared an Element typealias in sub-protocols, but that is separate from the proposal.

On 09 May 2016, at 07:28, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

If the protocol Sequence has typealias Element, does that mean I also have MyConformingSequence.Element?

If so, I think there is a potential impact on existing code not mentioned. Suppose MyConformingSequence already (unwisely) declares typealias Element. Now, what happens when I try to migrate my code to your proposed version of Swift?

This is a toy example, of course. More generally, though, I wonder about this question:

Suppose two protocols A and B each declare typealias Element. These typealiases are, as you proposed, intended to simplify referencing indirect associated types. But are they themselves considered protocol requirements?

I ask because, suppose I want to conform type T to A and B. I implement all the required methods and properties for such conformance. I declare the appropriate typealiases for the associatedtypes declared in both protocols. But, if A.Element and B.Element are incompatible with each other, it is nonetheless impossible to conform T to both A and B? If it's forbidden, isn't that kind of a bummer, since what's getting in the way is a naming clash arising from a facility intended to simplify the naming of things rather than provide for new functionality? If it's permitted, what is T.Element? Some clarity here would be nice.
On Sun, May 8, 2016 at 6:17 PM David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hello,

I’ve come again with another proposal directly from the Generics Manifesto. Please let me know if it needs any modifications before sending the pull request.

Typealiases in protocols and protocol extensions

Proposal: SE-XXXX <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
Authors: David Hart <https://github.com/hartbit>, Doug Gregor <https://github.com/DougGregor>
Status: TBD
Review manager: TBD
<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>Introduction

This proposal is from the Generics Manifesto <https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside of protocols to declare type aliases and in protocols to declare associated types. Since SE-0011 <https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and Swift 2.2, associated type now use the associatedtype keyword and typelias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed solution

The solution allows the creation of associated type aliases. Here is an example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}
The example above shows how this simplifies referencing indirect associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}
<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed design

The following grammar rules needs to be added:

protocol-member-declaration → protocol-typealias-declaration

protocol-typealias-declaration → typealias-declaration

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact on existing code

This will have no impact on existing code, but will probably require improving the Fix-It that was created for migrating typealias to associatedtype in Swift 2.2.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Xiaodi Wu) #8

I agree with you that similar issues exist with the status quo. I'm not
asking that you fix them with your proposal, just that you document how
your proposed feature will work--i.e. please include some of this stuff you
just wrote here somewhere in the proposal text.

Your question to the list solicited suggestions for modifications to your
proposal. Mine is to flesh out "proposed solution" and/or "detailed
design." In "proposed solution," you describe how what you're proposing
would be useful based on a lone example. Elsewhere, under "motivation" you
write that you're proposing "true associated type aliases"--what, exactly,
is that? how does it interact with type aliases in conforming types and in
sub-protocols? can they be overridden? can they be masked like non-default
methods in protocol extensions are currently? I don't really have a beef
with the proposal whether the answers are yes or no, but I'd like to know
what the answers are by reading the proposal.

···

On Mon, May 9, 2016 at 01:52 David Hart <david@hartbit.com> wrote:

I understand that name clashing in those instances is important to
discuss, but I still think it is slightly orthogonal to the proposal. Let
me try to explain why.

If typealises in protocols are to have the same semantics as alises
outside protocols (as I think they should), then they don’t change anything
about the rules of collision. For example, the problem already exists today
with associated types:

protocol Foo {
    associatedtype Inner: IntegerType
    func foo(inner: Inner)
}

protocol Bar {
    associatedtype Inner: FloatingPointType
    var inner: Inner { get }
}

struct FooBarImpl: Foo, Bar { // error: Type ‘FooBarImpl’ does not conform
to protocol ‘Bar'
    func foo(inner: Int) {}
    var inner: Float
}

Type aliasing would not change anything about the fact that those
collisions already exists in the language and are not very well handled:
either they are meant to be forbidden but in that case we need better
diagnostics, or we want to have a way to work around them. Perhaps you’d
like to start a discussion around fixing that ?

On 09 May 2016, at 08:06, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

I see your point that nothing breaks in the stdlib with your proposal
alone. It's undeniably true--by construction!--that a purely additive
feature, if never used, will not cause problems.

That said, since the time that this feature was outlined in Doug's
manifesto, I have been wondering how clashes such as the examples in my
previous email are to be handled--i.e. what the rules of the language are
to be--which I think is certainly germane to your proposal. Can a
conforming type override a protocol typealias? Can a type conform to two
protocols with conflicting typealiases if all requirements are otherwise
satisfied? Surely, these merit discussion in your proposal.

On Mon, May 9, 2016 at 12:48 AM David Hart <david@hartbit.com> wrote:

Hello Xiaodi,

What I mean by there is no impact on existing code is that the language
change has no impact. Of course, if the Standard Library then declares a
typealias Element in Sequence, it will clash with code which has declared
an Element typealias in sub-protocols, but that is separate from the
proposal.

On 09 May 2016, at 07:28, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

If the protocol Sequence has typealias Element, does that mean I also
have MyConformingSequence.Element?

If so, I think there is a potential impact on existing code not
mentioned. Suppose MyConformingSequence already (unwisely) declares
typealias Element. Now, what happens when I try to migrate my code to your
proposed version of Swift?

This is a toy example, of course. More generally, though, I wonder about
this question:

Suppose two protocols A and B each declare typealias Element. These
typealiases are, as you proposed, intended to simplify referencing indirect
associated types. But are they themselves considered protocol requirements?

I ask because, suppose I want to conform type T to A and B. I implement
all the required methods and properties for such conformance. I declare the
appropriate typealiases for the associatedtypes declared in both protocols.
But, if A.Element and B.Element are incompatible with each other, it is
nonetheless impossible to conform T to both A and B? If it's forbidden,
isn't that kind of a bummer, since what's getting in the way is a naming
clash arising from a facility intended to simplify the naming of things
rather than provide for new functionality? If it's permitted, what is
T.Element? Some clarity here would be nice.
On Sun, May 8, 2016 at 6:17 PM David Hart via swift-evolution < >> swift-evolution@swift.org> wrote:

Hello,

I’ve come again with another proposal directly from the Generics
Manifesto. Please let me know if it needs any modifications before sending
the pull request.

Typealiases in protocols and protocol extensions

   - Proposal: SE-XXXX
   <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
   - Authors: David Hart <https://github.com/hartbit>, Doug Gregor
   <https://github.com/DougGregor>
   - Status: TBD
   - Review manager: TBD

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>
Introduction

This proposal is from the Generics Manifesto
<https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and
brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>
Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside
of protocols to declare type aliases and in protocols to declare associated
types. Since SE-0011
<https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and
Swift 2.2, associated type now use the associatedtype keyword and
typelias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed
solution

The solution allows the creation of associated type aliases. Here is an
example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}

The example above shows how this simplifies referencing indirect
associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed
design

The following grammar rules needs to be added:

*protocol-member-declaration* → *protocol-typealias-declaration*

*protocol-typealias-declaration* → *typealias-declaration*

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact
on existing code
This will have no impact on existing code, but will probably require
improving the Fix-It that was created for migrating typealias to
associatedtype in Swift 2.2.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Xiaodi Wu) #9

One more thought here:

It goes a long way to say "typealiases in protocols are to have the same
semantics as aliases outside protocols." I'm inclined to agree on that, but
I haven't thought it totally through.

Now, I can have private typealiases outside protocols. Could I have private
typealiases inside protocols? They'd be handy for referencing types while
implementing default methods in protocol extensions and whatnot without
worrying about collisions with typealiases in conforming types...

···

On Mon, May 9, 2016 at 01:52 David Hart <david@hartbit.com> wrote:

I understand that name clashing in those instances is important to
discuss, but I still think it is slightly orthogonal to the proposal. Let
me try to explain why.

If typealises in protocols are to have the same semantics as alises
outside protocols (as I think they should), then they don’t change anything
about the rules of collision. For example, the problem already exists today
with associated types:

protocol Foo {
    associatedtype Inner: IntegerType
    func foo(inner: Inner)
}

protocol Bar {
    associatedtype Inner: FloatingPointType
    var inner: Inner { get }
}

struct FooBarImpl: Foo, Bar { // error: Type ‘FooBarImpl’ does not conform
to protocol ‘Bar'
    func foo(inner: Int) {}
    var inner: Float
}

Type aliasing would not change anything about the fact that those
collisions already exists in the language and are not very well handled:
either they are meant to be forbidden but in that case we need better
diagnostics, or we want to have a way to work around them. Perhaps you’d
like to start a discussion around fixing that ?

On 09 May 2016, at 08:06, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

I see your point that nothing breaks in the stdlib with your proposal
alone. It's undeniably true--by construction!--that a purely additive
feature, if never used, will not cause problems.

That said, since the time that this feature was outlined in Doug's
manifesto, I have been wondering how clashes such as the examples in my
previous email are to be handled--i.e. what the rules of the language are
to be--which I think is certainly germane to your proposal. Can a
conforming type override a protocol typealias? Can a type conform to two
protocols with conflicting typealiases if all requirements are otherwise
satisfied? Surely, these merit discussion in your proposal.

On Mon, May 9, 2016 at 12:48 AM David Hart <david@hartbit.com> wrote:

Hello Xiaodi,

What I mean by there is no impact on existing code is that the language
change has no impact. Of course, if the Standard Library then declares a
typealias Element in Sequence, it will clash with code which has declared
an Element typealias in sub-protocols, but that is separate from the
proposal.

On 09 May 2016, at 07:28, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

If the protocol Sequence has typealias Element, does that mean I also
have MyConformingSequence.Element?

If so, I think there is a potential impact on existing code not
mentioned. Suppose MyConformingSequence already (unwisely) declares
typealias Element. Now, what happens when I try to migrate my code to your
proposed version of Swift?

This is a toy example, of course. More generally, though, I wonder about
this question:

Suppose two protocols A and B each declare typealias Element. These
typealiases are, as you proposed, intended to simplify referencing indirect
associated types. But are they themselves considered protocol requirements?

I ask because, suppose I want to conform type T to A and B. I implement
all the required methods and properties for such conformance. I declare the
appropriate typealiases for the associatedtypes declared in both protocols.
But, if A.Element and B.Element are incompatible with each other, it is
nonetheless impossible to conform T to both A and B? If it's forbidden,
isn't that kind of a bummer, since what's getting in the way is a naming
clash arising from a facility intended to simplify the naming of things
rather than provide for new functionality? If it's permitted, what is
T.Element? Some clarity here would be nice.
On Sun, May 8, 2016 at 6:17 PM David Hart via swift-evolution < >> swift-evolution@swift.org> wrote:

Hello,

I’ve come again with another proposal directly from the Generics
Manifesto. Please let me know if it needs any modifications before sending
the pull request.

Typealiases in protocols and protocol extensions

   - Proposal: SE-XXXX
   <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
   - Authors: David Hart <https://github.com/hartbit>, Doug Gregor
   <https://github.com/DougGregor>
   - Status: TBD
   - Review manager: TBD

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>
Introduction

This proposal is from the Generics Manifesto
<https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and
brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>
Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside
of protocols to declare type aliases and in protocols to declare associated
types. Since SE-0011
<https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and
Swift 2.2, associated type now use the associatedtype keyword and
typelias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed
solution

The solution allows the creation of associated type aliases. Here is an
example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}

The example above shows how this simplifies referencing indirect
associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed
design

The following grammar rules needs to be added:

*protocol-member-declaration* → *protocol-typealias-declaration*

*protocol-typealias-declaration* → *typealias-declaration*

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact
on existing code
This will have no impact on existing code, but will probably require
improving the Fix-It that was created for migrating typealias to
associatedtype in Swift 2.2.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Xiaodi Wu) #10

Great, I hope this proposal finds much success with the community.

One more thing: your title makes mention of protocol extensions, but
protocol extensions are mentioned nowhere else. Please include details on
typealiases in protocol extensions within the text or remove it altogether
from the proposal.

···

On Mon, May 9, 2016 at 02:24 David Hart <david@hartbit.com> wrote:

On 09 May 2016, at 08:53, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

And to clarify, FWIW, I think it'd be wonderful to implement this feature,
and I share your sense that sometimes conversations on this list get a
little sidetracked. My comments are not meant to suggest that this is not a
good feature; rather, they go to your question to the list--does your
proposal need any modifications before a PR?

IMO, some sections need to be fleshed out. Some discussion on how your
proposed rules interact with other aspects of the language when they are
used in the daily task of conforming types to protocols is called for. I
accept your point that perhaps it doesn't belong in the 'Impact on Existing
Code' section.

I’ll add something.

I hope you'll forgive me for saying that the proposal seems, overall,
hastily written. That there are two misspelled instances of "typealias" in
a proposal about typealias does not give one confidence that what is
proposed has been sufficiently considered.

I don’t mind you saying it, it is a very early draft. That’s why I’m
putting it in front of the community before sending it for a Pull Request.

On Mon, May 9, 2016 at 01:06 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

I see your point that nothing breaks in the stdlib with your proposal
alone. It's undeniably true--by construction!--that a purely additive
feature, if never used, will not cause problems.

That said, since the time that this feature was outlined in Doug's
manifesto, I have been wondering how clashes such as the examples in my
previous email are to be handled--i.e. what the rules of the language are
to be--which I think is certainly germane to your proposal. Can a
conforming type override a protocol typealias? Can a type conform to two
protocols with conflicting typealiases if all requirements are otherwise
satisfied? Surely, these merit discussion in your proposal.

On Mon, May 9, 2016 at 12:48 AM David Hart <david@hartbit.com> wrote:

Hello Xiaodi,

What I mean by there is no impact on existing code is that the language
change has no impact. Of course, if the Standard Library then declares a
typealias Element in Sequence, it will clash with code which has declared
an Element typealias in sub-protocols, but that is separate from the
proposal.

On 09 May 2016, at 07:28, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

If the protocol Sequence has typealias Element, does that mean I also
have MyConformingSequence.Element?

If so, I think there is a potential impact on existing code not
mentioned. Suppose MyConformingSequence already (unwisely) declares
typealias Element. Now, what happens when I try to migrate my code to your
proposed version of Swift?

This is a toy example, of course. More generally, though, I wonder about
this question:

Suppose two protocols A and B each declare typealias Element. These
typealiases are, as you proposed, intended to simplify referencing indirect
associated types. But are they themselves considered protocol requirements?

I ask because, suppose I want to conform type T to A and B. I implement
all the required methods and properties for such conformance. I declare the
appropriate typealiases for the associatedtypes declared in both protocols.
But, if A.Element and B.Element are incompatible with each other, it is
nonetheless impossible to conform T to both A and B? If it's forbidden,
isn't that kind of a bummer, since what's getting in the way is a naming
clash arising from a facility intended to simplify the naming of things
rather than provide for new functionality? If it's permitted, what is
T.Element? Some clarity here would be nice.
On Sun, May 8, 2016 at 6:17 PM David Hart via swift-evolution < >>> swift-evolution@swift.org> wrote:

Hello,

I’ve come again with another proposal directly from the Generics
Manifesto. Please let me know if it needs any modifications before sending
the pull request.

Typealiases in protocols and protocol extensions

   - Proposal: SE-XXXX
   <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
   - Authors: David Hart <https://github.com/hartbit>, Doug Gregor
   <https://github.com/DougGregor>
   - Status: TBD
   - Review manager: TBD

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>
Introduction

This proposal is from the Generics Manifesto
<https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and
brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>
Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside
of protocols to declare type aliases and in protocols to declare associated
types. Since SE-0011
<https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and
Swift 2.2, associated type now use the associatedtype keyword and
typelias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed
solution

The solution allows the creation of associated type aliases. Here is an
example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}

The example above shows how this simplifies referencing indirect
associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed
design

The following grammar rules needs to be added:

*protocol-member-declaration* → *protocol-typealias-declaration*

*protocol-typealias-declaration* → *typealias-declaration*

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact
on existing code
This will have no impact on existing code, but will probably require
improving the Fix-It that was created for migrating typealias to
associatedtype in Swift 2.2.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(David Hart) #11

One more thought here:

It goes a long way to say "typealiases in protocols are to have the same semantics as aliases outside protocols." I'm inclined to agree on that, but I haven't thought it totally through.

Now, I can have private typealiases outside protocols. Could I have private typealiases inside protocols? They'd be handy for referencing types while implementing default methods in protocol extensions and whatnot without worrying about collisions with typealiases in conforming types…

Sounds like it should be allowed. I’ll add something about it in the proposal. Could you give an example of what you mean by "without worrying about collisions with typealiases in conforming types…”?

···

On 09 May 2016, at 09:16, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, May 9, 2016 at 01:52 David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:
I understand that name clashing in those instances is important to discuss, but I still think it is slightly orthogonal to the proposal. Let me try to explain why.

If typealises in protocols are to have the same semantics as alises outside protocols (as I think they should), then they don’t change anything about the rules of collision. For example, the problem already exists today with associated types:

protocol Foo {
    associatedtype Inner: IntegerType
    func foo(inner: Inner)
}

protocol Bar {
    associatedtype Inner: FloatingPointType
    var inner: Inner { get }
}

struct FooBarImpl: Foo, Bar { // error: Type ‘FooBarImpl’ does not conform to protocol ‘Bar'
    func foo(inner: Int) {}
    var inner: Float
}

Type aliasing would not change anything about the fact that those collisions already exists in the language and are not very well handled: either they are meant to be forbidden but in that case we need better diagnostics, or we want to have a way to work around them. Perhaps you’d like to start a discussion around fixing that ?

On 09 May 2016, at 08:06, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

I see your point that nothing breaks in the stdlib with your proposal alone. It's undeniably true--by construction!--that a purely additive feature, if never used, will not cause problems.

That said, since the time that this feature was outlined in Doug's manifesto, I have been wondering how clashes such as the examples in my previous email are to be handled--i.e. what the rules of the language are to be--which I think is certainly germane to your proposal. Can a conforming type override a protocol typealias? Can a type conform to two protocols with conflicting typealiases if all requirements are otherwise satisfied? Surely, these merit discussion in your proposal.

On Mon, May 9, 2016 at 12:48 AM David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:
Hello Xiaodi,

What I mean by there is no impact on existing code is that the language change has no impact. Of course, if the Standard Library then declares a typealias Element in Sequence, it will clash with code which has declared an Element typealias in sub-protocols, but that is separate from the proposal.

On 09 May 2016, at 07:28, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

If the protocol Sequence has typealias Element, does that mean I also have MyConformingSequence.Element?

If so, I think there is a potential impact on existing code not mentioned. Suppose MyConformingSequence already (unwisely) declares typealias Element. Now, what happens when I try to migrate my code to your proposed version of Swift?

This is a toy example, of course. More generally, though, I wonder about this question:

Suppose two protocols A and B each declare typealias Element. These typealiases are, as you proposed, intended to simplify referencing indirect associated types. But are they themselves considered protocol requirements?

I ask because, suppose I want to conform type T to A and B. I implement all the required methods and properties for such conformance. I declare the appropriate typealiases for the associatedtypes declared in both protocols. But, if A.Element and B.Element are incompatible with each other, it is nonetheless impossible to conform T to both A and B? If it's forbidden, isn't that kind of a bummer, since what's getting in the way is a naming clash arising from a facility intended to simplify the naming of things rather than provide for new functionality? If it's permitted, what is T.Element? Some clarity here would be nice.
On Sun, May 8, 2016 at 6:17 PM David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hello,

I’ve come again with another proposal directly from the Generics Manifesto. Please let me know if it needs any modifications before sending the pull request.

Typealiases in protocols and protocol extensions

Proposal: SE-XXXX <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
Authors: David Hart <https://github.com/hartbit>, Doug Gregor <https://github.com/DougGregor>
Status: TBD
Review manager: TBD
<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>Introduction

This proposal is from the Generics Manifesto <https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside of protocols to declare type aliases and in protocols to declare associated types. Since SE-0011 <https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and Swift 2.2, associated type now use the associatedtype keyword and typelias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed solution

The solution allows the creation of associated type aliases. Here is an example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}
The example above shows how this simplifies referencing indirect associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}
<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed design

The following grammar rules needs to be added:

protocol-member-declaration → protocol-typealias-declaration

protocol-typealias-declaration → typealias-declaration

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact on existing code

This will have no impact on existing code, but will probably require improving the Fix-It that was created for migrating typealias to associatedtype in Swift 2.2.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(David Hart) #12

Great, I hope this proposal finds much success with the community.

One more thing: your title makes mention of protocol extensions, but protocol extensions are mentioned nowhere else. Please include details on typealiases in protocol extensions within the text or remove it altogether from the proposal.

I left it in for now because it was explicitly mentioned in the Generics Manifesto (the title is a simple copy and paste), but I have yet to find good examples to illustrate their usefulness. Perhaps you could help me out on this one?

···

On 09 May 2016, at 09:30, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, May 9, 2016 at 02:24 David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:

On 09 May 2016, at 08:53, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

And to clarify, FWIW, I think it'd be wonderful to implement this feature, and I share your sense that sometimes conversations on this list get a little sidetracked. My comments are not meant to suggest that this is not a good feature; rather, they go to your question to the list--does your proposal need any modifications before a PR?

IMO, some sections need to be fleshed out. Some discussion on how your proposed rules interact with other aspects of the language when they are used in the daily task of conforming types to protocols is called for. I accept your point that perhaps it doesn't belong in the 'Impact on Existing Code' section.

I’ll add something.

I hope you'll forgive me for saying that the proposal seems, overall, hastily written. That there are two misspelled instances of "typealias" in a proposal about typealias does not give one confidence that what is proposed has been sufficiently considered.

I don’t mind you saying it, it is a very early draft. That’s why I’m putting it in front of the community before sending it for a Pull Request.

On Mon, May 9, 2016 at 01:06 Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:
I see your point that nothing breaks in the stdlib with your proposal alone. It's undeniably true--by construction!--that a purely additive feature, if never used, will not cause problems.

That said, since the time that this feature was outlined in Doug's manifesto, I have been wondering how clashes such as the examples in my previous email are to be handled--i.e. what the rules of the language are to be--which I think is certainly germane to your proposal. Can a conforming type override a protocol typealias? Can a type conform to two protocols with conflicting typealiases if all requirements are otherwise satisfied? Surely, these merit discussion in your proposal.

On Mon, May 9, 2016 at 12:48 AM David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:
Hello Xiaodi,

What I mean by there is no impact on existing code is that the language change has no impact. Of course, if the Standard Library then declares a typealias Element in Sequence, it will clash with code which has declared an Element typealias in sub-protocols, but that is separate from the proposal.

On 09 May 2016, at 07:28, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

If the protocol Sequence has typealias Element, does that mean I also have MyConformingSequence.Element?

If so, I think there is a potential impact on existing code not mentioned. Suppose MyConformingSequence already (unwisely) declares typealias Element. Now, what happens when I try to migrate my code to your proposed version of Swift?

This is a toy example, of course. More generally, though, I wonder about this question:

Suppose two protocols A and B each declare typealias Element. These typealiases are, as you proposed, intended to simplify referencing indirect associated types. But are they themselves considered protocol requirements?

I ask because, suppose I want to conform type T to A and B. I implement all the required methods and properties for such conformance. I declare the appropriate typealiases for the associatedtypes declared in both protocols. But, if A.Element and B.Element are incompatible with each other, it is nonetheless impossible to conform T to both A and B? If it's forbidden, isn't that kind of a bummer, since what's getting in the way is a naming clash arising from a facility intended to simplify the naming of things rather than provide for new functionality? If it's permitted, what is T.Element? Some clarity here would be nice.
On Sun, May 8, 2016 at 6:17 PM David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hello,

I’ve come again with another proposal directly from the Generics Manifesto. Please let me know if it needs any modifications before sending the pull request.

Typealiases in protocols and protocol extensions

Proposal: SE-XXXX <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
Authors: David Hart <https://github.com/hartbit>, Doug Gregor <https://github.com/DougGregor>
Status: TBD
Review manager: TBD
<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>Introduction

This proposal is from the Generics Manifesto <https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside of protocols to declare type aliases and in protocols to declare associated types. Since SE-0011 <https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and Swift 2.2, associated type now use the associatedtype keyword and typelias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed solution

The solution allows the creation of associated type aliases. Here is an example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}
The example above shows how this simplifies referencing indirect associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}
<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed design

The following grammar rules needs to be added:

protocol-member-declaration → protocol-typealias-declaration

protocol-typealias-declaration → typealias-declaration

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact on existing code

This will have no impact on existing code, but will probably require improving the Fix-It that was created for migrating typealias to associatedtype in Swift 2.2.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Xiaodi Wu) #13

Great, I hope this proposal finds much success with the community.

One more thing: your title makes mention of protocol extensions, but
protocol extensions are mentioned nowhere else. Please include details on
typealiases in protocol extensions within the text or remove it altogether
from the proposal.

I left it in for now because it was explicitly mentioned in the Generics
Manifesto (the title is a simple copy and paste), but I have yet to find
good examples to illustrate their usefulness. Perhaps you could help me out
on this one?

Nothing's coming to mind right off the bat. Perhaps the writer of the
Manifesto could chime in...

···

On Mon, May 9, 2016 at 2:33 AM, David Hart <david@hartbit.com> wrote:

On 09 May 2016, at 09:30, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, May 9, 2016 at 02:24 David Hart <david@hartbit.com> wrote:

On 09 May 2016, at 08:53, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

And to clarify, FWIW, I think it'd be wonderful to implement this
feature, and I share your sense that sometimes conversations on this list
get a little sidetracked. My comments are not meant to suggest that this is
not a good feature; rather, they go to your question to the list--does your
proposal need any modifications before a PR?

IMO, some sections need to be fleshed out. Some discussion on how your
proposed rules interact with other aspects of the language when they are
used in the daily task of conforming types to protocols is called for. I
accept your point that perhaps it doesn't belong in the 'Impact on Existing
Code' section.

I’ll add something.

I hope you'll forgive me for saying that the proposal seems, overall,
hastily written. That there are two misspelled instances of "typealias" in
a proposal about typealias does not give one confidence that what is
proposed has been sufficiently considered.

I don’t mind you saying it, it is a very early draft. That’s why I’m
putting it in front of the community before sending it for a Pull Request.

On Mon, May 9, 2016 at 01:06 Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

I see your point that nothing breaks in the stdlib with your proposal
alone. It's undeniably true--by construction!--that a purely additive
feature, if never used, will not cause problems.

That said, since the time that this feature was outlined in Doug's
manifesto, I have been wondering how clashes such as the examples in my
previous email are to be handled--i.e. what the rules of the language are
to be--which I think is certainly germane to your proposal. Can a
conforming type override a protocol typealias? Can a type conform to two
protocols with conflicting typealiases if all requirements are otherwise
satisfied? Surely, these merit discussion in your proposal.

On Mon, May 9, 2016 at 12:48 AM David Hart <david@hartbit.com> wrote:

Hello Xiaodi,

What I mean by there is no impact on existing code is that the language
change has no impact. Of course, if the Standard Library then declares a
typealias Element in Sequence, it will clash with code which has declared
an Element typealias in sub-protocols, but that is separate from the
proposal.

On 09 May 2016, at 07:28, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

If the protocol Sequence has typealias Element, does that mean I also
have MyConformingSequence.Element?

If so, I think there is a potential impact on existing code not
mentioned. Suppose MyConformingSequence already (unwisely) declares
typealias Element. Now, what happens when I try to migrate my code to your
proposed version of Swift?

This is a toy example, of course. More generally, though, I wonder
about this question:

Suppose two protocols A and B each declare typealias Element. These
typealiases are, as you proposed, intended to simplify referencing indirect
associated types. But are they themselves considered protocol requirements?

I ask because, suppose I want to conform type T to A and B. I implement
all the required methods and properties for such conformance. I declare the
appropriate typealiases for the associatedtypes declared in both protocols.
But, if A.Element and B.Element are incompatible with each other, it is
nonetheless impossible to conform T to both A and B? If it's forbidden,
isn't that kind of a bummer, since what's getting in the way is a naming
clash arising from a facility intended to simplify the naming of things
rather than provide for new functionality? If it's permitted, what is
T.Element? Some clarity here would be nice.
On Sun, May 8, 2016 at 6:17 PM David Hart via swift-evolution < >>>> swift-evolution@swift.org> wrote:

Hello,

I’ve come again with another proposal directly from the Generics
Manifesto. Please let me know if it needs any modifications before sending
the pull request.

Typealiases in protocols and protocol extensions

   - Proposal: SE-XXXX
   <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
   - Authors: David Hart <https://github.com/hartbit>, Doug Gregor
   <https://github.com/DougGregor>
   - Status: TBD
   - Review manager: TBD

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>
Introduction

This proposal is from the Generics Manifesto
<https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and
brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>
Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside
of protocols to declare type aliases and in protocols to declare associated
types. Since SE-0011
<https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and
Swift 2.2, associated type now use the associatedtype keyword and
typelias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed
solution

The solution allows the creation of associated type aliases. Here is
an example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}

The example above shows how this simplifies referencing indirect
associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed
design

The following grammar rules needs to be added:

*protocol-member-declaration* → *protocol-typealias-declaration*

*protocol-typealias-declaration* → *typealias-declaration*

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact
on existing code
This will have no impact on existing code, but will probably require
improving the Fix-It that was created for migrating typealias to
associatedtype in Swift 2.2.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Xiaodi Wu) #14

One more thought here:

It goes a long way to say "typealiases in protocols are to have the same
semantics as aliases outside protocols." I'm inclined to agree on that, but
I haven't thought it totally through.

Now, I can have private typealiases outside protocols. Could I have
private typealiases inside protocols? They'd be handy for referencing types
while implementing default methods in protocol extensions and whatnot
without worrying about collisions with typealiases in conforming types…

Sounds like it should be allowed. I’ll add something about it in the
proposal. Could you give an example of what you mean by "without worrying
about collisions with typealiases in conforming types…”?

I wonder if this takes things in an, um, interesting direction. Suppose I
could have this (a contrived example--it may fall apart on further study):

protocol MyUsefulProtocol {
  associatedtype Storage : Collection
  fileprivate typealias UniqueIdentifier = Storage.Index
  func doUsefulThing() -> Storage
}

extension MyUsefulProtocol {
  func doUsefulThing() -> Storage {
    // do something useful in this default implementation
    // use UniqueIdentifier internally here and only here
  }
}

In a different file:

struct MyUsefulType<A : Hashable, B> : MyUsefulProtocol {
  /* I could do this if I wanted:
  typealias UniqueIdentifier = A

  More importantly, I could retroactively conform MyUsefulType
  to MyUsefulProtocol even if they happen to have clashing
  typealiases, which is great because the typealias in
  MyUsefulProtocol is used for clarity and convenience inside
  the default implementation and is irrelevant here
  */
  func doUsefulThing() -> Dictionary<A, B> {
    // do something useful but different
    // from the default implementation
  }
}

I wonder, though, if this is to be allowed, whether much the same could be
achieved by instead allowing associatedtype declarations to have default
values (for example: `associatedtype UniqueIdentifier : Equatable =
Storage.Index`), at which point we might be one step away from going full
circle and eliminating the distinction between associatedtypes and
typealiases once again.

···

On Mon, May 9, 2016 at 2:31 AM, David Hart <david@hartbit.com> wrote:

On 09 May 2016, at 09:16, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, May 9, 2016 at 01:52 David Hart <david@hartbit.com> wrote:

I understand that name clashing in those instances is important to
discuss, but I still think it is slightly orthogonal to the proposal. Let
me try to explain why.

If typealises in protocols are to have the same semantics as alises
outside protocols (as I think they should), then they don’t change anything
about the rules of collision. For example, the problem already exists today
with associated types:

protocol Foo {
    associatedtype Inner: IntegerType
    func foo(inner: Inner)
}

protocol Bar {
    associatedtype Inner: FloatingPointType
    var inner: Inner { get }
}

struct FooBarImpl: Foo, Bar { // error: Type ‘FooBarImpl’ does not
conform to protocol ‘Bar'
    func foo(inner: Int) {}
    var inner: Float
}

Type aliasing would not change anything about the fact that those
collisions already exists in the language and are not very well handled:
either they are meant to be forbidden but in that case we need better
diagnostics, or we want to have a way to work around them. Perhaps you’d
like to start a discussion around fixing that ?

On 09 May 2016, at 08:06, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

I see your point that nothing breaks in the stdlib with your proposal
alone. It's undeniably true--by construction!--that a purely additive
feature, if never used, will not cause problems.

That said, since the time that this feature was outlined in Doug's
manifesto, I have been wondering how clashes such as the examples in my
previous email are to be handled--i.e. what the rules of the language are
to be--which I think is certainly germane to your proposal. Can a
conforming type override a protocol typealias? Can a type conform to two
protocols with conflicting typealiases if all requirements are otherwise
satisfied? Surely, these merit discussion in your proposal.

On Mon, May 9, 2016 at 12:48 AM David Hart <david@hartbit.com> wrote:

Hello Xiaodi,

What I mean by there is no impact on existing code is that the language
change has no impact. Of course, if the Standard Library then declares a
typealias Element in Sequence, it will clash with code which has declared
an Element typealias in sub-protocols, but that is separate from the
proposal.

On 09 May 2016, at 07:28, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

If the protocol Sequence has typealias Element, does that mean I also
have MyConformingSequence.Element?

If so, I think there is a potential impact on existing code not
mentioned. Suppose MyConformingSequence already (unwisely) declares
typealias Element. Now, what happens when I try to migrate my code to your
proposed version of Swift?

This is a toy example, of course. More generally, though, I wonder about
this question:

Suppose two protocols A and B each declare typealias Element. These
typealiases are, as you proposed, intended to simplify referencing indirect
associated types. But are they themselves considered protocol requirements?

I ask because, suppose I want to conform type T to A and B. I implement
all the required methods and properties for such conformance. I declare the
appropriate typealiases for the associatedtypes declared in both protocols.
But, if A.Element and B.Element are incompatible with each other, it is
nonetheless impossible to conform T to both A and B? If it's forbidden,
isn't that kind of a bummer, since what's getting in the way is a naming
clash arising from a facility intended to simplify the naming of things
rather than provide for new functionality? If it's permitted, what is
T.Element? Some clarity here would be nice.
On Sun, May 8, 2016 at 6:17 PM David Hart via swift-evolution < >>> swift-evolution@swift.org> wrote:

Hello,

I’ve come again with another proposal directly from the Generics
Manifesto. Please let me know if it needs any modifications before sending
the pull request.

Typealiases in protocols and protocol extensions

   - Proposal: SE-XXXX
   <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
   - Authors: David Hart <https://github.com/hartbit>, Doug Gregor
   <https://github.com/DougGregor>
   - Status: TBD
   - Review manager: TBD

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>
Introduction

This proposal is from the Generics Manifesto
<https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and
brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>
Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside
of protocols to declare type aliases and in protocols to declare associated
types. Since SE-0011
<https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and
Swift 2.2, associated type now use the associatedtype keyword and
typelias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed
solution

The solution allows the creation of associated type aliases. Here is an
example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}

The example above shows how this simplifies referencing indirect
associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed
design

The following grammar rules needs to be added:

*protocol-member-declaration* → *protocol-typealias-declaration*

*protocol-typealias-declaration* → *typealias-declaration*

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact
on existing code
This will have no impact on existing code, but will probably require
improving the Fix-It that was created for migrating typealias to
associatedtype in Swift 2.2.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(David Hart) #15

I don’t see a problem with your example. Because the typealias is fileprivate, it doesn’t exist as far as MyUsefulType is concerned. The same way the following works:

class Base {
    private typealias Foo = Int
    func foo() -> Int {
        return Foo()
    }
}

Other file:

class Derived: Base {
    typealias Foo = String
    func bar() -> String {
        return "Hello \(foo())"
    }
}
···

On 09 May 2016, at 10:37, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, May 9, 2016 at 2:31 AM, David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:

On 09 May 2016, at 09:16, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

One more thought here:

It goes a long way to say "typealiases in protocols are to have the same semantics as aliases outside protocols." I'm inclined to agree on that, but I haven't thought it totally through.

Now, I can have private typealiases outside protocols. Could I have private typealiases inside protocols? They'd be handy for referencing types while implementing default methods in protocol extensions and whatnot without worrying about collisions with typealiases in conforming types…

Sounds like it should be allowed. I’ll add something about it in the proposal. Could you give an example of what you mean by "without worrying about collisions with typealiases in conforming types…”?

I wonder if this takes things in an, um, interesting direction. Suppose I could have this (a contrived example--it may fall apart on further study):

protocol MyUsefulProtocol {
  associatedtype Storage : Collection
  fileprivate typealias UniqueIdentifier = Storage.Index
  func doUsefulThing() -> Storage
}

extension MyUsefulProtocol {
  func doUsefulThing() -> Storage {
    // do something useful in this default implementation
    // use UniqueIdentifier internally here and only here
  }
}

In a different file:

struct MyUsefulType<A : Hashable, B> : MyUsefulProtocol {
  /* I could do this if I wanted:
  typealias UniqueIdentifier = A
 
  More importantly, I could retroactively conform MyUsefulType
  to MyUsefulProtocol even if they happen to have clashing
  typealiases, which is great because the typealias in
  MyUsefulProtocol is used for clarity and convenience inside
  the default implementation and is irrelevant here
  */
  func doUsefulThing() -> Dictionary<A, B> {
    // do something useful but different
    // from the default implementation
  }
}

I wonder, though, if this is to be allowed, whether much the same could be achieved by instead allowing associatedtype declarations to have default values (for example: `associatedtype UniqueIdentifier : Equatable = Storage.Index`), at which point we might be one step away from going full circle and eliminating the distinction between associatedtypes and typealiases once again.

On Mon, May 9, 2016 at 01:52 David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:
I understand that name clashing in those instances is important to discuss, but I still think it is slightly orthogonal to the proposal. Let me try to explain why.

If typealises in protocols are to have the same semantics as alises outside protocols (as I think they should), then they don’t change anything about the rules of collision. For example, the problem already exists today with associated types:

protocol Foo {
    associatedtype Inner: IntegerType
    func foo(inner: Inner)
}

protocol Bar {
    associatedtype Inner: FloatingPointType
    var inner: Inner { get }
}

struct FooBarImpl: Foo, Bar { // error: Type ‘FooBarImpl’ does not conform to protocol ‘Bar'
    func foo(inner: Int) {}
    var inner: Float
}

Type aliasing would not change anything about the fact that those collisions already exists in the language and are not very well handled: either they are meant to be forbidden but in that case we need better diagnostics, or we want to have a way to work around them. Perhaps you’d like to start a discussion around fixing that ?

On 09 May 2016, at 08:06, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

I see your point that nothing breaks in the stdlib with your proposal alone. It's undeniably true--by construction!--that a purely additive feature, if never used, will not cause problems.

That said, since the time that this feature was outlined in Doug's manifesto, I have been wondering how clashes such as the examples in my previous email are to be handled--i.e. what the rules of the language are to be--which I think is certainly germane to your proposal. Can a conforming type override a protocol typealias? Can a type conform to two protocols with conflicting typealiases if all requirements are otherwise satisfied? Surely, these merit discussion in your proposal.

On Mon, May 9, 2016 at 12:48 AM David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:
Hello Xiaodi,

What I mean by there is no impact on existing code is that the language change has no impact. Of course, if the Standard Library then declares a typealias Element in Sequence, it will clash with code which has declared an Element typealias in sub-protocols, but that is separate from the proposal.

On 09 May 2016, at 07:28, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

If the protocol Sequence has typealias Element, does that mean I also have MyConformingSequence.Element?

If so, I think there is a potential impact on existing code not mentioned. Suppose MyConformingSequence already (unwisely) declares typealias Element. Now, what happens when I try to migrate my code to your proposed version of Swift?

This is a toy example, of course. More generally, though, I wonder about this question:

Suppose two protocols A and B each declare typealias Element. These typealiases are, as you proposed, intended to simplify referencing indirect associated types. But are they themselves considered protocol requirements?

I ask because, suppose I want to conform type T to A and B. I implement all the required methods and properties for such conformance. I declare the appropriate typealiases for the associatedtypes declared in both protocols. But, if A.Element and B.Element are incompatible with each other, it is nonetheless impossible to conform T to both A and B? If it's forbidden, isn't that kind of a bummer, since what's getting in the way is a naming clash arising from a facility intended to simplify the naming of things rather than provide for new functionality? If it's permitted, what is T.Element? Some clarity here would be nice.
On Sun, May 8, 2016 at 6:17 PM David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hello,

I’ve come again with another proposal directly from the Generics Manifesto. Please let me know if it needs any modifications before sending the pull request.

Typealiases in protocols and protocol extensions

Proposal: SE-XXXX <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
Authors: David Hart <https://github.com/hartbit>, Doug Gregor <https://github.com/DougGregor>
Status: TBD
Review manager: TBD
<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>Introduction

This proposal is from the Generics Manifesto <https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside of protocols to declare type aliases and in protocols to declare associated types. Since SE-0011 <https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and Swift 2.2, associated type now use the associatedtype keyword and typelias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed solution

The solution allows the creation of associated type aliases. Here is an example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}
The example above shows how this simplifies referencing indirect associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}
<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed design

The following grammar rules needs to be added:

protocol-member-declaration → protocol-typealias-declaration

protocol-typealias-declaration → typealias-declaration

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact on existing code

This will have no impact on existing code, but will probably require improving the Fix-It that was created for migrating typealias to associatedtype in Swift 2.2.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Xiaodi Wu) #16

Sorry--I'm not at all saying that I think there's a problem. As you asked,
I attempted to supply a contrived use case for a typealias declared in a
protocol having a more restricted scope than the protocol itself. I was
asking if it would be supported as part of your proposal.

···

On Mon, May 9, 2016 at 3:11 PM, David Hart <david@hartbit.com> wrote:

I don’t see a problem with your example. Because the typealias is
fileprivate, it doesn’t exist as far as MyUsefulType is concerned. The same
way the following works:

class Base {
    private typealias Foo = Int
    func foo() -> Int {
        return Foo()
    }
}

Other file:

class Derived: Base {
    typealias Foo = String
    func bar() -> String {
        return "Hello \(foo())"
    }
}

On 09 May 2016, at 10:37, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Mon, May 9, 2016 at 2:31 AM, David Hart <david@hartbit.com> wrote:

On 09 May 2016, at 09:16, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

One more thought here:

It goes a long way to say "typealiases in protocols are to have the same
semantics as aliases outside protocols." I'm inclined to agree on that, but
I haven't thought it totally through.

Now, I can have private typealiases outside protocols. Could I have
private typealiases inside protocols? They'd be handy for referencing types
while implementing default methods in protocol extensions and whatnot
without worrying about collisions with typealiases in conforming types…

Sounds like it should be allowed. I’ll add something about it in the
proposal. Could you give an example of what you mean by "without worrying
about collisions with typealiases in conforming types…”?

I wonder if this takes things in an, um, interesting direction. Suppose I
could have this (a contrived example--it may fall apart on further study):

protocol MyUsefulProtocol {
  associatedtype Storage : Collection
  fileprivate typealias UniqueIdentifier = Storage.Index
  func doUsefulThing() -> Storage
}

extension MyUsefulProtocol {
  func doUsefulThing() -> Storage {
    // do something useful in this default implementation
    // use UniqueIdentifier internally here and only here
  }
}

In a different file:

struct MyUsefulType<A : Hashable, B> : MyUsefulProtocol {
  /* I could do this if I wanted:
  typealias UniqueIdentifier = A

  More importantly, I could retroactively conform MyUsefulType
  to MyUsefulProtocol even if they happen to have clashing
  typealiases, which is great because the typealias in
  MyUsefulProtocol is used for clarity and convenience inside
  the default implementation and is irrelevant here
  */
  func doUsefulThing() -> Dictionary<A, B> {
    // do something useful but different
    // from the default implementation
  }
}

I wonder, though, if this is to be allowed, whether much the same could be
achieved by instead allowing associatedtype declarations to have default
values (for example: `associatedtype UniqueIdentifier : Equatable =
Storage.Index`), at which point we might be one step away from going full
circle and eliminating the distinction between associatedtypes and
typealiases once again.

On Mon, May 9, 2016 at 01:52 David Hart <david@hartbit.com> wrote:

I understand that name clashing in those instances is important to
discuss, but I still think it is slightly orthogonal to the proposal. Let
me try to explain why.

If typealises in protocols are to have the same semantics as alises
outside protocols (as I think they should), then they don’t change anything
about the rules of collision. For example, the problem already exists today
with associated types:

protocol Foo {
    associatedtype Inner: IntegerType
    func foo(inner: Inner)
}

protocol Bar {
    associatedtype Inner: FloatingPointType
    var inner: Inner { get }
}

struct FooBarImpl: Foo, Bar { // error: Type ‘FooBarImpl’ does not
conform to protocol ‘Bar'
    func foo(inner: Int) {}
    var inner: Float
}

Type aliasing would not change anything about the fact that those
collisions already exists in the language and are not very well handled:
either they are meant to be forbidden but in that case we need better
diagnostics, or we want to have a way to work around them. Perhaps you’d
like to start a discussion around fixing that ?

On 09 May 2016, at 08:06, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

I see your point that nothing breaks in the stdlib with your proposal
alone. It's undeniably true--by construction!--that a purely additive
feature, if never used, will not cause problems.

That said, since the time that this feature was outlined in Doug's
manifesto, I have been wondering how clashes such as the examples in my
previous email are to be handled--i.e. what the rules of the language are
to be--which I think is certainly germane to your proposal. Can a
conforming type override a protocol typealias? Can a type conform to two
protocols with conflicting typealiases if all requirements are otherwise
satisfied? Surely, these merit discussion in your proposal.

On Mon, May 9, 2016 at 12:48 AM David Hart <david@hartbit.com> wrote:

Hello Xiaodi,

What I mean by there is no impact on existing code is that the language
change has no impact. Of course, if the Standard Library then declares a
typealias Element in Sequence, it will clash with code which has declared
an Element typealias in sub-protocols, but that is separate from the
proposal.

On 09 May 2016, at 07:28, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

If the protocol Sequence has typealias Element, does that mean I also
have MyConformingSequence.Element?

If so, I think there is a potential impact on existing code not
mentioned. Suppose MyConformingSequence already (unwisely) declares
typealias Element. Now, what happens when I try to migrate my code to your
proposed version of Swift?

This is a toy example, of course. More generally, though, I wonder
about this question:

Suppose two protocols A and B each declare typealias Element. These
typealiases are, as you proposed, intended to simplify referencing indirect
associated types. But are they themselves considered protocol requirements?

I ask because, suppose I want to conform type T to A and B. I implement
all the required methods and properties for such conformance. I declare the
appropriate typealiases for the associatedtypes declared in both protocols.
But, if A.Element and B.Element are incompatible with each other, it is
nonetheless impossible to conform T to both A and B? If it's forbidden,
isn't that kind of a bummer, since what's getting in the way is a naming
clash arising from a facility intended to simplify the naming of things
rather than provide for new functionality? If it's permitted, what is
T.Element? Some clarity here would be nice.
On Sun, May 8, 2016 at 6:17 PM David Hart via swift-evolution < >>>> swift-evolution@swift.org> wrote:

Hello,

I’ve come again with another proposal directly from the Generics
Manifesto. Please let me know if it needs any modifications before sending
the pull request.

Typealiases in protocols and protocol extensions

   - Proposal: SE-XXXX
   <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
   - Authors: David Hart <https://github.com/hartbit>, Doug Gregor
   <https://github.com/DougGregor>
   - Status: TBD
   - Review manager: TBD

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>
Introduction

This proposal is from the Generics Manifesto
<https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and
brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>
Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside
of protocols to declare type aliases and in protocols to declare associated
types. Since SE-0011
<https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and
Swift 2.2, associated type now use the associatedtype keyword and
typelias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed
solution

The solution allows the creation of associated type aliases. Here is
an example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}

The example above shows how this simplifies referencing indirect
associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed
design

The following grammar rules needs to be added:

*protocol-member-declaration* → *protocol-typealias-declaration*

*protocol-typealias-declaration* → *typealias-declaration*

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact
on existing code
This will have no impact on existing code, but will probably require
improving the Fix-It that was created for migrating typealias to
associatedtype in Swift 2.2.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(David Hart) #17

Hi everybody,

I added details suggested by Xiaodi and opened a pull request. Any last minute modifications before it gets merged in?

https://github.com/hartbit/swift-evolution/blob/a1b883132588bd0ceff5e5c9787bcef140f6674a/proposals/XXXX-typealiases-in-protocols.md

Typealiases in protocols and protocol extensions

Proposal: SE-XXXX <https://github.com/hartbit/swift-evolution/blob/a1b883132588bd0ceff5e5c9787bcef140f6674a/proposals/XXXX-typealiases-in-protocols.md>
Authors: David Hart <https://github.com/hartbit>, Doug Gregor <https://github.com/DougGregor>
Status: TBD
Review manager: TBD
<https://github.com/hartbit/swift-evolution/blob/a1b883132588bd0ceff5e5c9787bcef140f6674a/proposals/XXXX-typealiases-in-protocols.md#introduction>Introduction

This proposal is from the Generics Manifesto <https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/a1b883132588bd0ceff5e5c9787bcef140f6674a/proposals/XXXX-typealiases-in-protocols.md#motivation>Motivation

In Swift versions prior to 2.2, the typealias keyword was used outside of protocols to declare type aliases and in protocols to declare associated types. Since SE-0011 <https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and Swift 2.2, associated type now use the associatedtypekeyword and typealias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/a1b883132588bd0ceff5e5c9787bcef140f6674a/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed solution

The solution allows the creation of associated type aliases. Here is an example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}
The example above shows how this simplifies referencing indirect associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}
Allowing typealias in protocol extensions also allows extensions to use aliases to simplify code that the protocol did not originally propose:

extension Sequence {
    typealias Element = Iterator.Element

    func concat(other: Self) -> [Element] {
        return Array<Element>(self) + Array<Element>(other)
    }
}
<https://github.com/hartbit/swift-evolution/blob/a1b883132588bd0ceff5e5c9787bcef140f6674a/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed design

The following grammar rules needs to be added:

protocol-member-declaration → protocol-typealias-declaration

protocol-typealias-declaration → typealias-declaration

<https://github.com/hartbit/swift-evolution/blob/a1b883132588bd0ceff5e5c9787bcef140f6674a/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact on existing code

This will initially have no impact on existing code, but will probably require improving the Fix-It that was created for migrating typealias to associatedtype in Swift 2.2.

But once typealias starts being used inside protocols, especially in the Standard Library, name clashes might start cropping up between the type aliases and associated types. For example:

protocol Sequence {
    typealias Element = Iterator.Element // once this is added
}

protocol MySequence: Sequence {
    associatedtype Element // MySequence.Element is ambiguous
}
But there is no reason that those name clashes behave differently than current clashes between associated types:

protocol Foo {
    associatedtype Inner: IntegerType
    func foo(inner: Inner)
}

protocol Bar {
    associatedtype Inner: FloatingPointType
    var inner: Inner { get }
}

struct FooBarImpl: Foo, Bar { // error: Type ‘FooBarImpl’ does not conform to protocol ‘Bar'
    func foo(inner: Int) {}
    var inner: Float
}

···

On 09 May 2016, at 22:18, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

Sorry--I'm not at all saying that I think there's a problem. As you asked, I attempted to supply a contrived use case for a typealias declared in a protocol having a more restricted scope than the protocol itself. I was asking if it would be supported as part of your proposal.

On Mon, May 9, 2016 at 3:11 PM, David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:
I don’t see a problem with your example. Because the typealias is fileprivate, it doesn’t exist as far as MyUsefulType is concerned. The same way the following works:

class Base {
    private typealias Foo = Int
    func foo() -> Int {
        return Foo()
    }
}

Other file:

class Derived: Base {
    typealias Foo = String
    func bar() -> String {
        return "Hello \(foo())"
    }
}

On 09 May 2016, at 10:37, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

On Mon, May 9, 2016 at 2:31 AM, David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:

On 09 May 2016, at 09:16, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

One more thought here:

It goes a long way to say "typealiases in protocols are to have the same semantics as aliases outside protocols." I'm inclined to agree on that, but I haven't thought it totally through.

Now, I can have private typealiases outside protocols. Could I have private typealiases inside protocols? They'd be handy for referencing types while implementing default methods in protocol extensions and whatnot without worrying about collisions with typealiases in conforming types…

Sounds like it should be allowed. I’ll add something about it in the proposal. Could you give an example of what you mean by "without worrying about collisions with typealiases in conforming types…”?

I wonder if this takes things in an, um, interesting direction. Suppose I could have this (a contrived example--it may fall apart on further study):

protocol MyUsefulProtocol {
  associatedtype Storage : Collection
  fileprivate typealias UniqueIdentifier = Storage.Index
  func doUsefulThing() -> Storage
}

extension MyUsefulProtocol {
  func doUsefulThing() -> Storage {
    // do something useful in this default implementation
    // use UniqueIdentifier internally here and only here
  }
}

In a different file:

struct MyUsefulType<A : Hashable, B> : MyUsefulProtocol {
  /* I could do this if I wanted:
  typealias UniqueIdentifier = A
 
  More importantly, I could retroactively conform MyUsefulType
  to MyUsefulProtocol even if they happen to have clashing
  typealiases, which is great because the typealias in
  MyUsefulProtocol is used for clarity and convenience inside
  the default implementation and is irrelevant here
  */
  func doUsefulThing() -> Dictionary<A, B> {
    // do something useful but different
    // from the default implementation
  }
}

I wonder, though, if this is to be allowed, whether much the same could be achieved by instead allowing associatedtype declarations to have default values (for example: `associatedtype UniqueIdentifier : Equatable = Storage.Index`), at which point we might be one step away from going full circle and eliminating the distinction between associatedtypes and typealiases once again.

On Mon, May 9, 2016 at 01:52 David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:
I understand that name clashing in those instances is important to discuss, but I still think it is slightly orthogonal to the proposal. Let me try to explain why.

If typealises in protocols are to have the same semantics as alises outside protocols (as I think they should), then they don’t change anything about the rules of collision. For example, the problem already exists today with associated types:

protocol Foo {
    associatedtype Inner: IntegerType
    func foo(inner: Inner)
}

protocol Bar {
    associatedtype Inner: FloatingPointType
    var inner: Inner { get }
}

struct FooBarImpl: Foo, Bar { // error: Type ‘FooBarImpl’ does not conform to protocol ‘Bar'
    func foo(inner: Int) {}
    var inner: Float
}

Type aliasing would not change anything about the fact that those collisions already exists in the language and are not very well handled: either they are meant to be forbidden but in that case we need better diagnostics, or we want to have a way to work around them. Perhaps you’d like to start a discussion around fixing that ?

On 09 May 2016, at 08:06, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

I see your point that nothing breaks in the stdlib with your proposal alone. It's undeniably true--by construction!--that a purely additive feature, if never used, will not cause problems.

That said, since the time that this feature was outlined in Doug's manifesto, I have been wondering how clashes such as the examples in my previous email are to be handled--i.e. what the rules of the language are to be--which I think is certainly germane to your proposal. Can a conforming type override a protocol typealias? Can a type conform to two protocols with conflicting typealiases if all requirements are otherwise satisfied? Surely, these merit discussion in your proposal.

On Mon, May 9, 2016 at 12:48 AM David Hart <david@hartbit.com <mailto:david@hartbit.com>> wrote:
Hello Xiaodi,

What I mean by there is no impact on existing code is that the language change has no impact. Of course, if the Standard Library then declares a typealias Element in Sequence, it will clash with code which has declared an Element typealias in sub-protocols, but that is separate from the proposal.

On 09 May 2016, at 07:28, Xiaodi Wu <xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>> wrote:

If the protocol Sequence has typealias Element, does that mean I also have MyConformingSequence.Element?

If so, I think there is a potential impact on existing code not mentioned. Suppose MyConformingSequence already (unwisely) declares typealias Element. Now, what happens when I try to migrate my code to your proposed version of Swift?

This is a toy example, of course. More generally, though, I wonder about this question:

Suppose two protocols A and B each declare typealias Element. These typealiases are, as you proposed, intended to simplify referencing indirect associated types. But are they themselves considered protocol requirements?

I ask because, suppose I want to conform type T to A and B. I implement all the required methods and properties for such conformance. I declare the appropriate typealiases for the associatedtypes declared in both protocols. But, if A.Element and B.Element are incompatible with each other, it is nonetheless impossible to conform T to both A and B? If it's forbidden, isn't that kind of a bummer, since what's getting in the way is a naming clash arising from a facility intended to simplify the naming of things rather than provide for new functionality? If it's permitted, what is T.Element? Some clarity here would be nice.
On Sun, May 8, 2016 at 6:17 PM David Hart via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hello,

I’ve come again with another proposal directly from the Generics Manifesto. Please let me know if it needs any modifications before sending the pull request.

Typealiases in protocols and protocol extensions

Proposal: SE-XXXX <https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md>
Authors: David Hart <https://github.com/hartbit>, Doug Gregor <https://github.com/DougGregor>
Status: TBD
Review manager: TBD
<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#introduction>Introduction

This proposal is from the Generics Manifesto <https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md> and brings the typealias keyword back into protocols for type aliasing.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#motivation>Motivation

In Swift versions prior to 2.2, the typelias keyword was used outside of protocols to declare type aliases and in protocols to declare associated types. Since SE-0011 <https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md> and Swift 2.2, associated type now use the associatedtype keyword and typelias is available for implementing true associated type aliases.

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#proposed-solution>Proposed solution

The solution allows the creation of associated type aliases. Here is an example from the standard library:

protocol Sequence {
  associatedtype Iterator : IteratorProtocol
  typealias Element = Iterator.Element
}
The example above shows how this simplifies referencing indirect associated types:

func sum<T: Sequence where T.Element == Int>(sequence: T) -> Int {
    return sequence.reduce(0, combine: +)
}
<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#detailed-design>Detailed design

The following grammar rules needs to be added:

protocol-member-declaration → protocol-typealias-declaration

protocol-typealias-declaration → typealias-declaration

<https://github.com/hartbit/swift-evolution/blob/typealiases-in-protocols/proposals/XXXX-typealiases-in-protocols.md#impact-on-existing-code>Impact on existing code

This will have no impact on existing code, but will probably require improving the Fix-It that was created for migrating typealias to associatedtype in Swift 2.2.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution