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

Reply via email to