> On 1 Feb 2017, at 22:54, Douglas Gregor <[email protected]> wrote:
> 
> 
>> 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?

Well what would it mean? A protocol can't inherit or conform to a class.

>       - Doug
> 
>> Slava
>> 
>>> On Jan 29, 2017, at 8:39 AM, David Hart via swift-evolution 
>>> <[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
>>> 
>>> Regards,
>>> David.
>>> 
>>> Existentials for classes conforming to protocols
>>> Proposal: SE-XXXX
>>> Authors: David Hart, Austin Zheng
>>> Review Manager: TBD
>>> Status: TBD
>>> 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.
>>> 
>>> 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.
>>> 
>>> 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
>>> 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.
>>> Alternatives considered
>>> 
>>> None.
>>> 
>>> Acknowledgements
>>> 
>>> Thanks to Austin Zheng and Matthew Johnson 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]
>>> 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

Reply via email to