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