[swift-evolution] Subclass Existentials
Jordan Rose
jordan_rose at apple.com
Wed Feb 1 17:06:43 CST 2017
I agree with Chris on both counts. Either we need to continue to import ‘NSFoo <NSBar> *’ as ‘NSFoo’ in the Swift 4 compiler’s “Swift 3 compatibility mode”, or we need to come up with all the cases where a normally-unsound conversion needs to be permitted (possibly with a warning) in order to avoid breaking existing programs. The latter is technically doable, but would be much more work, which would likely hurt the proposal’s chances of getting into Swift 4.
Thank you for writing this up, David!
Jordan
> On Jan 29, 2017, at 12:17, Chris Lattner via swift-evolution <swift-evolution at swift.org> wrote:
>
> +1 on the proposal overall. You might want to clarify the writing wrt source compatibility though. The new syntax and type system mechanics should work in Swift 3 mode, it is just the importer change that must be conditionalized.
>
> -Chris
>
> On Jan 29, 2017, at 8:39 AM, David Hart via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> 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
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170201/fe31cb94/attachment.html>
More information about the swift-evolution
mailing list