Re: [swift-evolution] [Pitch] Self's nominal restriction denies significant feature patterns

2017-06-03 Thread Joe Groff via swift-evolution

> On Jun 2, 2017, at 3:08 AM, Zaid Daghestani via swift-evolution 
>  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
> 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 { 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?

Yes, `Self` in classes is currently restricted to being the return type of a 
method. This could eventually be generalized to allow `Self` in any covariant 
position within a class method type, and in fact SE-0068 
(https://github.com/apple/swift-evolution/blob/master/proposals/0068-universal-self.md)
 was accepted to allow this generalization, but we haven't done the 
implementation work to enable it yet.

-Joe
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Self's nominal restriction denies significant feature patterns

2017-06-02 Thread Gwendal Roué via swift-evolution
The key is to implement methods that deal with Self as protocol extensions. Not 
*in* the protocol itself:

// YES
protocol DAOProtocol {
init()
}

extension DAOProtocol {
static func retOne() -> Self {return self.init()}
static func retMany() -> Array { return [] }
static func retTuple() -> (Self, Int) { return (self.init(), 0) }
}

// NO
// protocol DAOProtocol {
// init()
// static func retOne() -> Self
// static func retMany() -> Array
// static func retTuple() -> (Self, Int)
// }

class Selfie : DAOProtocol{
required init() {}
}

Selfie.retOne()
Selfie.retMany()
Selfie.retTuple()

Beware: methods declared in protocol extensions *can not be customized* by 
adopting types. Only methods declared in the protocol itself can, and become 
customization points. This is an important constraint to think about when you 
design your protocols. Again, GRDB can be of great help for you: it has been 
working well for almost two years now.

Gwendal


> Le 2 juin 2017 à 12:10, Zaid Daghestani  a écrit :
> 
> *edit*
> Actual protocol implementation:
> 
> protocol Selfie {
> init()
> }
> extension Selfie {
> static func retOne() -> Self {return self.init()}
> static func retMany() -> Array { return [] }
> static func retTuple() -> (Self, Int) { return (self.init(), 0) }
> }
> 
> 
>> On Jun 2, 2017, at 3:08 AM, Zaid Daghestani > > 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
>> 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 { 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é >> > 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: 
>>> 
>>> 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 
 > 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 
  s (Ref. 1 for examples). There are a 
 

Re: [swift-evolution] [Pitch] Self's nominal restriction denies significant feature patterns

2017-06-02 Thread Zaid Daghestani via swift-evolution
*edit*
Actual protocol implementation:

protocol Selfie {
init()
}
extension Selfie {
static func retOne() -> Self {return self.init()}
static func retMany() -> Array { return [] }
static func retTuple() -> (Self, Int) { return (self.init(), 0) }
}


> On Jun 2, 2017, at 3:08 AM, Zaid Daghestani  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
> 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 { 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é > > 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: 
>> 
>> 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 
>>> > 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 
>>>  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 

Re: [swift-evolution] [Pitch] Self's nominal restriction denies significant feature patterns

2017-06-02 Thread Zaid Daghestani via swift-evolution
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
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 { 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é  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: 
> 
> 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 
>> > 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 
>>  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) // 

Re: [swift-evolution] [Pitch] Self's nominal restriction denies significant feature patterns

2017-06-02 Thread Gwendal Roué via swift-evolution
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:

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 
>  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 
>  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 {
> 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, a lazy 
> collection
> class func `where`(_ predication:NSPredicate) -> Results {
> return Results()
> }

[swift-evolution] [Pitch] Self's nominal restriction denies significant feature patterns

2017-06-02 Thread Zaid Daghestani via swift-evolution
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 
 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 {
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, a lazy 
collection
class func `where`(_ predication:NSPredicate) -> Results {
return Results()
}
}

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`(_ predicate:String, _ 
args:CVarArg...) -> Promise<[T]> {
// querie
return Promise(value: [])
}

// some more examples
// optional async get
class func get(id:String) -> Promise {
return Promise(value:self.init(id:id))
}


// sync all collection
class func all() -> [T] {
return []
}
// asynnchronous fetch
class func allAsync() -> Promise<[T]> {
return Promise(value: [])
}

// in the case of RealmDB we have returns of Results, a lazy 
collection
class func `where`(_ predication:NSPredicate) -> 
Results {
return Results()
}
}

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