<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">I think this is essential for creating good, general-purpose abstractions with Swift.<div class=""><br class=""></div><div class="">For example, currently I have a protocol which models a CRUD database. There is some ORM behaviour which translates the DB information in to model objects, but of course, each database might have different requirements. Currently ORMs use class hierarchies to give you that behaviour - e.g. CoreData has NSManagedObject, Realm has its own “Object” class, etc. This requires that I write separate protocols for each base-type, like this:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class=""><font face="Courier" class="">protocol RealmObjectStore {</font></div></div><div class=""><div class=""><font face="Courier" class="">&nbsp; &nbsp; func create&lt;S&gt;(_ objects: S) where S: Sequence, S.Element: RealmSwift.Object</font></div></div><div class=""><div class=""><font face="Courier" class="">&nbsp; &nbsp; func read&lt;T&gt;(_ command: FetchCommand&lt;T&gt;) -&gt; [T] where T: RealmSwift.Object</font></div></div><div class=""><div class=""><font face="Courier" class="">&nbsp; &nbsp; // …etc</font></div></div><div class=""><div class=""><font face="Courier" class="">}</font></div></div></blockquote><div class=""><br class=""></div><div class="">Ideally, my my protocol would look something like this:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Courier" class="">protocol ObjectStore {</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; associatedtype Storable // might be a concrete type; might be a protocol.</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; func create&lt;S&gt;(_ objects: S) where S: Sequence, S.Element: Self.</font><span style="font-family: Courier;" class="">Storable</span></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; func read&lt;T&gt;(_ command: FetchCommand&lt;T&gt;) -&gt; [T] where T: Self.</font><span style="font-family: Courier;" class="">Storable</span></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; // …etc</font></div><div class=""><font face="Courier" class="">}</font></div></blockquote><div class=""><br class=""></div><div class="">That would allow me to abstract over CoreData and Realm using a single protocol, as far as they are both able to act like CRUD databases:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Courier" class="">class CoreDataStore: ObjectStore {</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; typealias Storable = NSManagedObject</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp;// …etc</font></div><div class=""><font face="Courier" class="">}</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">class RealmDataStore: ObjectStore {</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp; typealias Storable = RealmObject</font></div><div class=""><font face="Courier" class="">&nbsp; &nbsp;// …etc</font></div><div class=""><font face="Courier" class="">}</font></div><div class=""><font face="Courier" class=""><br class=""></font></div></blockquote>Okay, so technically I could do that today by requiring that Storable is a subclass of NSObject. But doing this would also us to move beyond class hierarchies - what does an ObjectStore really need to store and retrieve its data? Well, that depends on the store. Maybe some will require all of the dynamism and reflection of Objective-C, and so will continue to require subclassing, but maybe for some it will be enough to have Codable conformance and a primary key. You could satisfy that with a value-type:<div class=""><div class=""><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class=""><font face="Courier" class="">protocol ValueDBStorable: Codable {</font></div></div><div class=""><div class=""><font face="Courier" class="">&nbsp; &nbsp; var primaryKey: KeyPath&lt;Self, String&gt; { get }</font></div></div><div class=""><div class=""><font face="Courier" class="">}</font></div></div><div class=""><div class=""><font face="Courier" class=""><br class=""></font></div></div><div class=""><div class=""><font face="Courier" class="">class ValueDBStore: ObjectStore {</font></div></div><div class=""><div class=""><font face="Courier" class="">&nbsp; &nbsp; typealias Storable = ValueDBStorable</font></div></div><div class=""><div class=""><font face="Courier" class="">&nbsp; &nbsp; // …etc</font></div></div><div class=""><div class=""><font face="Courier" class="">}&nbsp;</font></div></div></blockquote><div class=""><div class=""><br class=""></div><div class="">So I think it’s a very powerful feature and would love to use it. However, I do think it would underscore the need for nested protocols.</div><div class=""><br class=""></div><div class="">- Karl</div><div class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On 25. Nov 2017, at 00:03, Matthew Johnson via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">One of the most frequent frustrations I encounter when writing generic code in Swift is the requirement that supertype constraints be concrete. &nbsp;When I mentioned this on Twitter (<a href="https://twitter.com/anandabits/status/929958479598534656" class="">https://twitter.com/anandabits/status/929958479598534656</a>) Doug Gregor mentioned that this feature is smaller and mostly straightforward to design and implement (<a href="https://twitter.com/dgregor79/status/929975472779288576" class="">https://twitter.com/dgregor79/status/929975472779288576</a>).<div class=""><div class=""><br class=""></div><div class="">I currently have a PR open to add the high-level description of this feature found below to the generics manifesto (<a href="https://github.com/apple/swift/pull/13012" class="">https://github.com/apple/swift/pull/13012</a>):</div><div class=""><br class=""></div><div class=""><div class="">Currently, supertype constraints may only be specified using a concrete class or protocol type. &nbsp;This prevents us from abstracting over the supertype.</div><div class=""><br class=""></div><div class="">```swift</div><div class="">protocol P {</div><div class="">&nbsp; associatedtype Base</div><div class="">&nbsp; associatedtype Derived: Base</div><div class="">}</div><div class="">```</div><div class=""><br class=""></div><div class="">In the above example `Base` may be any type. &nbsp;`Derived` may be the same as `Base` or may be _any_ subtype of `Base`. &nbsp;All subtype relationships supported by Swift should be supported in this context including, but not limited to, classes and subclasses, existentials and conforming concrete types or refining existentials, `T?` and &nbsp;`T`, `((Base) -&gt; Void)` and `((Derived) -&gt; Void)`, etc.</div><div class=""><br class=""></div><div class="">Generalized supertype constraints would be accepted in all syntactic locations where generic constraints are accepted.</div></div><div class=""><br class=""></div><div class="">I would like to see generalized supertype constraints make it into Swift 5 if possible. &nbsp;I am not an implementer so I will not be able to bring a proposal forward alone but am interested in collaborating with anyone interested in working on implementation.</div><div class=""><br class=""></div><div class="">I am also interested in hearing general feedback on this feature from the community at large. &nbsp;Have you also found this limitation frustrating? &nbsp;In what contexts? &nbsp;Does anyone have reservations about introducing this capability? &nbsp;If so, what are they?<div class=""><br class=""></div><div class=""><div class="">Matthew</div><div class=""><div class=""><br class=""></div></div></div></div></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><div class=""><br class=""></div></div></div></body></html>