> 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