*edit* Actual protocol implementation: protocol Selfie { init() } extension Selfie { static func retOne() -> Self {return self.init()} static func retMany() -> Array<Self> { return [] } static func retTuple() -> (Self, Int) { return (self.init(), 0) } }
> On Jun 2, 2017, at 3:08 AM, Zaid Daghestani <z...@itsunmute.com> wrote: > > Wow, you’re right. Look like this is a bug? The issue shows up in class > definitions, not protocol definitions. > > This works: > > protocol Selfie { > static func retOne() -> Self > static func retMany() -> Array<Self> > static func retTuple() -> (Self, Int) > } > > This doesn’t work: > > class Selfie { > required init() {} > // Compiles > static func retOne() -> Self {return self.init()} > // Doesn't Compile > static func retMany() -> Array<Self> { return [] } > // Doesn't Compile > static func retTuple() -> (Self, Int) { return (self.init(), 0) } > > } > > So Self in non-nominal types with class methods end up with the compiler > error: > > Error: 'Self' is only available in a protocol or as the result of a method in > a class; did you mean ’Selfie’? > > Can we get confirmation from anyone? > > > >> On Jun 2, 2017, at 2:39 AM, Gwendal Roué <gwendal.r...@gmail.com >> <mailto:gwendal.r...@gmail.com>> wrote: >> >> Hello Zaid, >> >> I don't know what prevents you from implementing your DAOs. >> >> For an example of a library that uses them extensively, see >> http://github.com/groue/GRDB.swift: <http://github.com/groue/GRDB.swift:> >> >> struct PointOfInterest { >> var id: Int64? >> var title: String? >> var favorite: Bool >> var coordinate: CLLocationCoordinate2D >> } >> >> // (snip) adopt protocols that turn PointOfInterest in a "record" >> >> // Fetch from SQL >> let pois = try PointOfInterest.fetchAll(db, "SELECT * FROM >> pointOfInterests") // [PointOfInterest] >> >> // Fetch without SQL >> let title = Column("title") >> let favorite = Column("favorite") >> let poi1 = try PointOfInterest.fetchOne(db, key: 1) // >> PointOfInterest? >> let pois = try PointOfInterest.fetchOne(db, keys: [1, 2, 3]) // >> [PointOfInterest] >> let paris = try PointOfInterest.filter(title == "Paris").fetchOne(db) // >> PointOfInterest? >> let favoritePois = try PointOfInterest // >> [PointOfInterest] >> .filter(favorite) >> .order(title) >> .fetchAll(db) >> >> // Insert, update, delete >> var berlin = PointOfInterest( >> id: nil, >> title: "Berlin", >> favorite: false, >> coordinate: CLLocationCoordinate2DMake(52.52437, 13.41053)) >> try berlin.insert(db) >> berlin.id // some value >> berlin.favorite = true >> try berlin.update(db) >> try berlin.delete(db) >> >> GRDB "records" work pretty well with structs, but also class hierarchies, >> without any caveat. >> >> Can you explain a little more your issue ? >> >> Gwendal Roué >> >> >>> Le 2 juin 2017 à 11:18, Zaid Daghestani via swift-evolution >>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit : >>> >>> Greetings Swift Community, >>> >>> Today I’m throwing out a pitch on freeing the shackles on Self. Self is a >>> potentially significant tool that I am itching to implement in my patterns >>> to make my code more concise, clear and intuitive. >>> >>> Self, by far, is cherished by Data Models and ORM's, and particularly DAO >>> <https://en.wikipedia.org/wiki/DAO> s (Ref. 1 for examples). There are a >>> significant amount of patterns in which a base class’s methods are Self >>> relevant and not generic relevant. Self being non-referrable in non-nominal >>> types denies significant feature and pattern delivery such as DAO. And to >>> deny implementation of a pattern as significant as DAO’s seems like a shot >>> in the foot. Adding Self to non-nominal types brings Collections and Async >>> to our class/protocol methods. A single query method returning a sync or >>> likely async collection on my DataModel class will be used in about 80% of >>> my app screens and 80% of my eerver API’s, almost all of the time. Hell >>> this even applies to struct patterns as well. >>> >>> Now, DAO’s can actually already currently be achieved via generics, see >>> Ref. 2. This actually still a pretty good implementation, but Self is a >>> significantly more true implementation of these patterns. Issues with the >>> current generic pattern of Self relevancy in Swift is: >>> 1- Generic methods in the base class are a workaround to the lack of Self. >>> The base class is not a class that implements generic patterns. It a base >>> class that implements Self patterns. Self is more concise and intuitive in >>> implementing a DAO or any other Self relevant base class. >>> 2- Self relevant patterns are distinct and not the same as Generic >>> patterns. >>> 3- In usage of a DAO, the generic pattern requires that the Left Hand Side >>> be typed to collapse the generic. In the case of Self relevance, the >>> particular class name is enough. Swift, being an inference language, would >>> be truer with the Self system, and not the repetitive type declaration >>> style of ObjC/Java that generics provide. >>> let friends = User.where("id IN %@", friendIds) // truer to Swift type >>> inference >>> // vs. >>> let friends:[User] = User.where("id IN %@", friendIds) // Java/Objective-C >>> style repetitive type declarations >>> >>> Let’s break the chains on Self! It is extremely intuitive, and we are all >>> going to use it >>> >>> Peace! >>> >>> Z >>> >>> >>> >>> >>> Ref 1: DAO patterns:: >>> >>> class DataModelObject { >>> >>> /* One of the most significant use cases >>> * Retrieving a queried on collection asynchronusly >>> */ >>> class func `where`(_ predicate:String, _ args:CVarArg...) -> >>> Promise<[Self]> { >>> // querie >>> return Promise(value: [[]) >>> } >>> >>> // some more examples >>> >>> // optional async get >>> class func get(id:String) -> Promise<Self?> { >>> return Promise(value:self.init(id:id)) >>> } >>> >>> // sync all collection >>> class func all() -> [Self] { >>> return [] >>> } >>> // asynnchronous fetch >>> class func allAsync() -> Promise<[Self]> { >>> return Promise(value: []) >>> } >>> >>> // in the case of RealmDB we have returns of Results<Self>, a lazy >>> collection >>> class func `where`(_ predication:NSPredicate) -> Results<Self> { >>> return Results<self>() >>> } >>> } >>> >>> class User : DataMadelObject { >>> dynamic var id:String = "" >>> dynamic var name:String = "" >>> } >>> >>> let friendIds = [1, 2, 3] >>> let friends = User.where("id IN %@", friendIds) >>> >>> Ref 2: Currently implementable DAO >>> >>> class DataModelObject { >>> >>> /* One of the most significant use cases >>> * Retrieving a queried on collection asynchronusly >>> */ >>> class func `where`<T: DataModelObject>(_ predicate:String, _ >>> args:CVarArg...) -> Promise<[T]> { >>> // querie >>> return Promise(value: []) >>> } >>> >>> // some more examples >>> // optional async get >>> class func <T: DataModelObject>get(id:String) -> Promise<T?> { >>> return Promise(value:self.init(id:id)) >>> } >>> >>> >>> // sync all collection >>> class func all<T: DataModelObject>() -> [T] { >>> return [] >>> } >>> // asynnchronous fetch >>> class func allAsync<T: DataModelObject>() -> Promise<[T]> { >>> return Promise(value: []) >>> } >>> >>> // in the case of RealmDB we have returns of Results<Self>, a lazy >>> collection >>> class func `where`<T: DataModelObject>(_ predication:NSPredicate) -> >>> Results<T> { >>> return Results<T>() >>> } >>> } >>> >>> class User : DataMadelObject { >>> dynamic var id:String = "" >>> dynamic var name:String = "" >>> } >>> >>> let friendIds = [1, 2, 3] >>> let friends:[User] = User.where("id IN %@", friendIds) >>> >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution