> On Jan 29, 2017, at 8:44 PM, Slava Pestov via swift-evolution
> <[email protected]> wrote:
>
> This is a nice generalization of the existing protocol composition syntax.
> Implementation might get a little tricky — this touches a lot of things, such
> as inheritance clauses, constraints in generic signatures, and casts. It
> would require thorough testing.
>
> There are also a few odd corner cases to sort out:
>
> typealias T = SomeClass & SomeProtocol
>
> class C : T { // should we allow this? probably yes
> }
>
> protocol P : T { // should we allow this? probably no
> }
IIRC, we already allow the latter where T is a typealias for SomeProtocol1 &
SomeProtocol2. Why not allow it generally?
- Doug
> Slava
>
>> On Jan 29, 2017, at 8:39 AM, David Hart via swift-evolution
>> <[email protected] <mailto:[email protected]>> wrote:
>>
>> Hello,
>>
>> As promised, I wrote the first draft of a proposal to add class requirements
>> to the existential syntax. Please let me know what you think.
>>
>> https://github.com/hartbit/swift-evolution/blob/subclass-existentials/proposals/XXXX-subclass-existentials.md
>>
>> <https://github.com/hartbit/swift-evolution/blob/subclass-existentials/proposals/XXXX-subclass-existentials.md>
>>
>> Regards,
>> David.
>>
>> Existentials for classes conforming to protocols
>>
>> Proposal: SE-XXXX
>> <https://github.com/hartbit/swift-evolution/blob/subclass-existentials/proposals/XXXX-subclass-existentials.md>
>> Authors: David Hart <http://github.com/hartbit/>, Austin Zheng
>> <http://github.com/austinzheng>
>> Review Manager: TBD
>> Status: TBD
>>
>> <https://github.com/hartbit/swift-evolution/tree/subclass-existentials/proposals#introduction>Introduction
>>
>> This proposal brings more expressive power to the type system by allowing
>> Swift to represent existentials of classes and subclasses which conform to
>> protocols.
>>
>>
>> <https://github.com/hartbit/swift-evolution/tree/subclass-existentials/proposals#motivation>Motivation
>>
>> Currently, the only existentials which can be represented in Swift are
>> conformances to a set of protocols, using the &syntax:
>>
>> let existential: Hashable & CustomStringConvertible
>> On the other hand, Objective-C is capable of expressing existentials of
>> subclasses conforming to protocols with the following syntax:
>>
>> UIViewController<UITableViewDataSource, UITableViewDelegate>* existential;
>> We propose to provide similar expressive power to Swift, which will also
>> improve the bridging of those types from Objective-C.
>>
>>
>> <https://github.com/hartbit/swift-evolution/tree/subclass-existentials/proposals#proposed-solution>Proposed
>> solution
>>
>> The proposal keeps the existing & syntax but allows the first element, and
>> only the first, to be of class type. The equivalent declaration to the above
>> Objective-C declaration would look like this:
>>
>> let existential: UIViewController & UITableViewDataSource &
>> UITableViewDelegate
>> As in Objective-C, this existential represents classes which have
>> UIViewController in their parent inheritance hierarchy and which also
>> conform to the UITableViewDataSource and UITableViewDelegate protocols.
>>
>> As only the first element in the existential composition syntax can be a
>> class type, and by extending this rule to typealias expansions, we can make
>> sure that we only need to read the first element to know if it contains a
>> class requirement. As a consequence, here is a list of valid and invalid
>> code and the reasons for them:
>>
>> let a: Hashable & CustomStringConvertible
>> // VALID: This is still valid, as before
>>
>> let b: MyObject & Hashable
>> // VALID: This is the new rule which allows an object type in first position
>>
>> let c: CustomStringConvertible & MyObject
>> // INVALID: MyObject is not allowed in second position. A fix-it should help
>> transform it to:
>> // let c: MyObject & CustomStringConvertible
>>
>> typealias MyObjectStringConvertible = MyObject & CustomStringConvertible
>> let d: Hashable & MyObjectStringConvertible
>> // INVALID: The typealias expansion means that the type of d expands to
>> Hashable & MyObject & CustomStringConvertible, which has the class in the
>> wrong position. A fix-it should help transform it to:
>> // let d: MyObjectStringConvertible & Hashable
>>
>> typealias MyObjectStringConvertible = MyObject & CustomStringConvertible
>> let e: MyOtherObject & MyObjectStringConvertible
>> // INVALID: The typealias expansion would allow an existential with two
>> class requirements, which is invalid
>> The following examples could technically be legal, but we believe we should
>> keep them invalid to keep the rules simple:
>>
>> let a: MyObject & MyObject & CustomStringConvertible
>> // This is equivalent to MyObject & CustomStringConvertible
>>
>> let b: MyObjectSubclass & MyObject & Hashable
>> // This is equivalent to MyObjectSubclass & Hashable
>>
>> typealias MyObjectStringConvertible = MyObject & CustomStringConvertible
>> let d: MyObject & MyObjectStringConvertible
>> // This is equivalent to MyObject & CustomStringConvertible
>>
>> <https://github.com/hartbit/swift-evolution/tree/subclass-existentials/proposals#source-compatibility>Source
>> compatibility
>>
>> This is a source breaking change. All types bridged from Objective-C which
>> use the equivalent Objective-C feature import without the protocol
>> conformances in Swift 3. This change would increase the existential's
>> requirement and break on code which does not meet the new protocol
>> requirements. For example, the following Objective-C code:
>>
>> @interface MyViewController
>> - (void)setup:(nonnull
>> UIViewController<UITableViewDataSource,UITableViewDelegate>*)tableViewController;
>> @end
>> is imported into Swift 3 as:
>>
>> class MyViewController {
>> func setup(tableViewController: UIViewController) {}
>> }
>> which allows calling the function with an invalid parameter:
>>
>> let myViewController: MyViewController()
>> myViewController.setup(UIViewController())
>> The previous code would have worked as long as the Objective-C code did not
>> call any method of UITableViewDataSource or UITableViewDelegate. But if this
>> proposal is accepted and implemented as-is, the Objective-C code would now
>> be imported as:
>>
>> class MyViewController {
>> func setup(tableViewController: UIViewController & UITableViewDataSource
>> & UITableViewDelegate) {}
>> }
>> That would then cause the Swift code to fail to compile with an error which
>> states that UIViewController does not conform to the UITableViewDataSource
>> and UITableViewDelegate protocols.
>>
>> It is a source-breaking change, but should have a minimal impact for the
>> following reasons:
>>
>> Not many Objective-C code used the existential syntax in practice.
>> There generated errors are a good thing because they point out potential
>> crashes which would have gone un-noticed.
>>
>> <https://github.com/hartbit/swift-evolution/tree/subclass-existentials/proposals#alternatives-considered>Alternatives
>> considered
>>
>> None.
>>
>>
>> <https://github.com/hartbit/swift-evolution/tree/subclass-existentials/proposals#acknowledgements>Acknowledgements
>>
>> Thanks to Austin Zheng <http://github.com/austinzheng> and Matthew Johnson
>> <https://github.com/anandabits> who brought a lot of attention to
>> existentials in this mailing-list and from whom most of the ideas in the
>> proposal come from.
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution