> On Feb 6, 2017, at 1:18 PM, David Hart <[email protected]> wrote:
> 
> Hello mailing-list,
> 
> I rewrote the draft proposal concerning the class and subclass existentials. 
> Please let me know what you think, especially concerning the class and 
> AnyObject conundrum.

Thanks for working on this! Some comments below.

        - Doug

> Regards,
> David.
> 
> https://github.com/hartbit/swift-evolution/blob/e6411d8a9e7924bbd8a48fc292bf08d58a8d1199/proposals/XXXX-subclass-existentials.md
>  
> <https://github.com/hartbit/swift-evolution/blob/e6411d8a9e7924bbd8a48fc292bf08d58a8d1199/proposals/XXXX-subclass-existentials.md>
> 
> Class and Subtype existentials
> 
> Proposal: SE-XXXX 
> <https://github.com/hartbit/swift-evolution/blob/e6411d8a9e7924bbd8a48fc292bf08d58a8d1199/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/blob/e6411d8a9e7924bbd8a48fc292bf08d58a8d1199/proposals/XXXX-subclass-existentials.md#introduction>Introduction
> 
> This proposal brings more expressive power to the type system by allowing 
> Swift to represent existentials of classes and subtypes which conform to 
> protocols.
> 
>  
> <https://github.com/hartbit/swift-evolution/blob/e6411d8a9e7924bbd8a48fc292bf08d58a8d1199/proposals/XXXX-subclass-existentials.md#motivation>Motivation
> 
> Currently, the only existentials which can be represented in Swift are 
> conformances to a set of protocols, using the &protocol composition syntax:
> 
> Protocol1 & Protocol2
> On the other hand, Objective-C is capable of expressing existentials of 
> classes and subclasses conforming to protocols with the following syntax:
> 
> id<Protocol1, Protocol2>
> Base<Protocol>*
> 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/blob/e6411d8a9e7924bbd8a48fc292bf08d58a8d1199/proposals/XXXX-subclass-existentials.md#proposed-solution>Proposed
>  solution
> 
> The proposal keeps the existing & syntax but allows the first element, and 
> only the first, to be either the class keyword or of class type. The 
> equivalent to the above Objective-C types would look like this:
> 
> class & Protocol1 & Protocol2
> Base & Protocol
> As in Objective-C, the first line is an existential of classes which conform 
> to Protocol1 and Protocol2, and the second line is an existential of subtypes 
> of Base which conform to Protocol.
> 
> Here are the new proposed rules for what is valid in a existential 
> conjunction syntax:
> 
>  
> <https://github.com/hartbit/swift-evolution/blob/e6411d8a9e7924bbd8a48fc292bf08d58a8d1199/proposals/XXXX-subclass-existentials.md#1-the-first-element-in-the-protocol-composition-syntax-can-be-the-class-keyword-to-enforce-a-class-constraint>1.
>  The first element in the protocol composition syntax can be the class 
> keyword to enforce a class constraint:
> 
> protocol P {}
> struct S : P {}
> class C : P {}
> let t: P & class // Compiler error: class requirement must be in first 
> position
> let u: class & P = S() // Compiler error: S is not of class type
> let v: class & P = C() // Compiles successfully
Is

        let w: class = C()

intended to work? (I believe the answer is “yes”)
> 2. The first element in the protocol composition syntax can be a class type 
> to enforce the existential to be a subtype of the class:
> 
> protocol P {}
> struct S {}
> class C {}
> class D : P {}
> class E : C, P {}
> let t: P & C // Compiler error: subclass contraint must be in first position
> let u: S & P // Compiler error: S is not of class type
> let v: C & P = D() // Compiler error: D is not a subtype of C
> let w: C & P = E() // Compiles successfully
Okay.
> 3. When a protocol composition type contains a typealias, the validity of the 
> type is determined using the following steps:
> 
> Expand the typealias
> Normalize the type by removing duplicate constraints and replacing less 
> specific constraints by more specific constraints (a class constraint is less 
> specific than a class type constraint, which is less specific than a 
> constraint of a subclass of that class).
> Check that the type does not contain two class-type constraints

Technically, if one class is a subclass of the other, we can take the subclass. 
We actually already do this in generic constraints:

        class C { }
        class D: C { }

        func f<T>(_: T) where T: C, T: D { }  // same as just "where T: D”

We could be more strict with existentials, but it seems unnecessary.
>  
> <https://github.com/hartbit/swift-evolution/blob/e6411d8a9e7924bbd8a48fc292bf08d58a8d1199/proposals/XXXX-subclass-existentials.md#class-and-anyobject>class
>  and AnyObject
> 
> This proposal merges the concepts of class and AnyObject, which now have the 
> same meaning: they represent an existential for classes. They are four 
> solutions to this dilemna:
> 
> Do nothing.
> Replace all uses of AnyObject by class, breaking source compatibility.
> Replace all uses of class by AnyObject, breaking source compatibility.
> Redefine AnyObject as typealias AnyObject = class.

Please pick one to propose; it improves clarify for the proposal to be 
specific. The others can go to “Alternatives considered”.

I suggest #4 :)

Also, I think it’s good to point out that

        extension AnyObject { }

is already banned, so making AnyObject not a protocol shouldn’t actually change 
what code is accepted.

> Source compatibility
> 
> Leaving aside what is decided concerning class and AnyObject, this change 
> will not break Swift 3 compability mode because Objective-C types will 
> continue to be imported as before. But in Swift 4 mode, all types bridged 
> from Objective-C which use the equivalent Objective-C existential syntax 
> could break code which does not meet the new protocol requirements.
> 

Can you make the “import Objective-C’s SomeClass<SomeProto> as SomeClass & 
SomeProto” bit its own section before “Source compatibility”? The “Source 
compatibility” bit is more informational and shouldn’t introduce additional 
parts of the proposal.

> For example, the following Objective-C code:
> 
> @interface MyViewController
> - (void)setup:(nonnull 
> UIViewController<UITableViewDataSource,UITableViewDelegate>*)tableViewController;
> @end
> is imported into Swift-3 mode 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 continues to compile but still crashs if the Objective-C 
> code calls a method of UITableViewDataSource or UITableViewDelegate. But if 
> this proposal is accepted and implemented as-is, the Objective-C code will be 
> imported in Swift 4 mode as:
> 
> class MyViewController {
>     func setup(tableViewController: UIViewController & UITableViewDataSource 
> & UITableViewDelegate) {}
> }
> That would then cause the Swift code run in version 4 mode to fail to compile 
> with an error which states that UIViewController does not conform to the 
> UITableViewDataSource and UITableViewDelegate protocols.
> 
>  
> <https://github.com/hartbit/swift-evolution/blob/e6411d8a9e7924bbd8a48fc292bf08d58a8d1199/proposals/XXXX-subclass-existentials.md#alternatives-considered>

        - Doug

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to