*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

Reply via email to