*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 <[email protected]> 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é <[email protected]
>> <mailto:[email protected]>> 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
>>> <[email protected] <mailto:[email protected]>> 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
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>
>
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution