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> 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 >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution