[Discussion] Generic protocols


(Adrian Zubarev) #1

Hi there, I wanted to ask if we need generic protocols in stage one or is it something for stage two? I literally bumped into a corner where I need them to write a nice and type safe API.

···

--
Adrian Zubarev
Sent with Airmail


(Daniel Leping) #2

Aren't protocols generic already using associatedtype?

Also, what I really would like to have is generic associatedtype. Basically
to work the very same way as typealias.

Another nice to have feature might be having a possibility to add the same
generic protocol several times with different type associated. It might be
a bad C++ habit, though. Still I really miss it sometimes :slight_smile:

What else is missing for me is possibility to declare a var or return type
by generic protocol. Have to create a specific class all the time which is
a big pain.

···

On Fri, 2 Dec 2016 at 18:36 Adrian Zubarev via swift-evolution < swift-evolution@swift.org> wrote:

Hi there, I wanted to ask if we need generic protocols in stage one or is
it something for stage two? I literally bumped into a corner where I need
them to write a nice and type safe API.

--
Adrian Zubarev
Sent with Airmail
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Adrian Zubarev) #3

The problem I bumped into is, that I cannot overload a function which uses an associated type, so I could pass that instance to different type which needs the other overloaded function. Only generic protocols could do this.

Something similar is described as the top of the Generic protocols section in the generics manifesto.

···

--
Adrian Zubarev
Sent with Airmail

Am 2. Dezember 2016 um 18:25:49, Daniel Leping (daniel@crossroadlabs.xyz) schrieb:

Aren't protocols generic already
using associatedtype?

Also, what I really would like to have is generic associatedtype.
Basically to work the very same way as typealias.

Another nice to have feature might be having a possibility to add
the same generic protocol several times with different type
associated. It might be a bad C++ habit, though. Still I really
miss it sometimes :slight_smile:

What else is missing for me is possibility to declare a var or
return type by generic protocol. Have to create a specific class
all the time which is a big pain.

On Fri, 2 Dec 2016 at 18:36 Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:
Hi there, I wanted to ask if we need generic protocols in stage one or is it something for stage two? I literally bumped into a corner where I need them to write a nice and type safe API.

--
Adrian Zubarev
Sent with Airmail
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Tino) #4

Aren't protocols generic already using associatedtype?

Not really:
Take a look at (for example) AnyIterator… this whole layer of indirection could be removed with the requested change.
You can declare a protocol that generates Ints, Strings or whatever you like — just not in a generic way, and that's a pity.


(Daniel Leping) #5

Could you, please, bring a code example?

···

On Fri, 2 Dec 2016 at 19:31 Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:

The problem I bumped into is, that I cannot overload a function which uses
an associated type, so I could pass that instance to different type which
needs the other overloaded function. Only generic protocols could do this.

Something similar is described as the top of the *Generic protocols*
section in the generics manifesto
<https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#generic-protocols>
.

--
Adrian Zubarev
Sent with Airmail

Am 2. Dezember 2016 um 18:25:49, Daniel Leping (daniel@crossroadlabs.xyz)
schrieb:

Aren't protocols generic already using associatedtype?

Also, what I really would like to have is generic associatedtype.
Basically to work the very same way as typealias.

Another nice to have feature might be having a possibility to add the same
generic protocol several times with different type associated. It might be
a bad C++ habit, though. Still I really miss it sometimes :slight_smile:

What else is missing for me is possibility to declare a var or return type
by generic protocol. Have to create a specific class all the time which is
a big pain.

On Fri, 2 Dec 2016 at 18:36 Adrian Zubarev via swift-evolution < > swift-evolution@swift.org> wrote:

Hi there, I wanted to ask if we need generic protocols in stage one or is
it something for stage two? I literally bumped into a corner where I need
them to write a nice and type safe API.

--
Adrian Zubarev
Sent with Airmail
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Adrian Zubarev) #6

Check out the thread called: How to rewrite this snippet without existentials?

On some classes I want to write something like this:

enum X {…}
enum Y {…}

class A : Connection<X>, Connection<Y> { … }

let a = A()

let router = Router<X>()
router.register(a)

···

--
Adrian Zubarev
Sent with Airmail

Am 2. Dezember 2016 um 18:32:47, Daniel Leping (daniel@crossroadlabs.xyz) schrieb:

Could you, please, bring a code
example?

On Fri, 2 Dec 2016 at 19:31 Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:
The problem I bumped into is, that I cannot overload a function which uses an associated type, so I could pass that instance to different type which needs the other overloaded function. Only generic protocols could do this.

Something similar is described as the top of the Generic protocols section in the generics manifesto.

--
Adrian Zubarev
Sent with Airmail

Am 2. Dezember 2016 um 18:25:49, Daniel Leping (daniel@crossroadlabs.xyz) schrieb:

Aren't protocols generic already using
associatedtype?

Also, what I really would like to have is generic associatedtype.
Basically to work the very same way as typealias.

Another nice to have feature might be having a possibility to add
the same generic protocol several times with different type
associated. It might be a bad C++ habit, though. Still I really
miss it sometimes :slight_smile:

What else is missing for me is possibility to declare a var or
return type by generic protocol. Have to create a specific class
all the time which is a big pain.

On Fri, 2 Dec 2016 at 18:36 Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:
Hi there, I wanted to ask if we need generic protocols in stage one or is it something for stage two? I literally bumped into a corner where I need them to write a nice and type safe API.

--
Adrian Zubarev
Sent with Airmail
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Adrian Zubarev) #7

I just overlooked that the subsection about generic protocols was inside the Unlikely section.

The problem is that I need a way to refer to a function with a specific name. Plus the connection type has to have a specific API, like having a DispatchQueue and know the router object if there is any (sounds like a protocol right?!). The function reference should also keep the connection object alive with a strong reference.

associatedtype does not solve that problem for me.

I clearly see that generic protocols overlap with associatedtype but couldn’t we find a compromise here? For instance like Chris Lattner introduced generic type aliases without the ability of constants.

···

--
Adrian Zubarev
Sent with Airmail

Am 2. Dezember 2016 um 18:41:15, Tino Heth (2th@gmx.de) schrieb:

Aren't protocols generic already using
associatedtype?
Not really:
Take a look at (for example) AnyIterator… this whole layer of indirection could be removed with the requested change.
You can declare a protocol that generates Ints, Strings or whatever you like — just not in a generic way, and that's a pity.


(Charles Srstka) #8

Why don’t we just use angle brackets to specify associated types? Protocols aren’t using them for anything anyway. Then you could:

if let someSequence as? Sequence<Iterator.Element == Int> { // do something }

which would form a nice parallel to the syntax for casting things to generic types.

Charles

···

On Dec 2, 2016, at 12:34 PM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I just overlooked that the subsection about generic protocols was inside the Unlikely section.

The problem is that I need a way to refer to a function with a specific name. Plus the connection type has to have a specific API, like having a DispatchQueue and know the router object if there is any (sounds like a protocol right?!). The function reference should also keep the connection object alive with a strong reference.

associatedtype does not solve that problem for me.

I clearly see that generic protocols overlap with associatedtype but couldn’t we find a compromise here? For instance like Chris Lattner introduced generic type aliases without the ability of constants.


(Karl) #9

Your problem is that you want to conform to the same protocol twice.
  
I've discussed ideas for how to support something like that. I'm not sure if it fits the core team's direction for swift.
  
Karl

···

  
On Dec 2, 2016 at 7:34 pm, <Adrian Zubarev via swift-evolution (mailto:swift-evolution@swift.org)> wrote:
  
I just overlooked that the subsection about generic protocols was inside the Unlikely section.

The problem is that I need a way to refer to a function with a specific name. Plus the connection type has to have a specific API, like having a DispatchQueue and know the router object if there is any (sounds like a protocol right?!). The function reference should also keep the connection object alive with a strong reference.

associatedtype does not solve that problem for me.

I clearly see that generic protocols overlap with associatedtype but couldn’t we find a compromise here? For instance like Chris Lattner introduced generic type aliases without the ability of constants.

--
Adrian Zubarev
Sent with Airmail
  
Am 2. Dezember 2016 um 18:41:15, Tino Heth (2th@gmx.de (mailto:2th@gmx.de)) schrieb:

>
>
>
>
>
>
>
> >
> > Aren't protocols generic already using associatedtype?
> > Not really:
> Take a look at (for example) AnyIterator… this whole layer of indirection could be removed with the requested change.
>
> You can declare a protocol that generates Ints, Strings or whatever you like — just not in a generic way, and that's a pity.
>
>
>
  
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org (mailto:swift-evolution@swift.org) https://lists.swift.org/mailman/listinfo/swift-evolution


(Adrian Zubarev) #10

I think I might found a solution that will satisfy generic protocols and not break the system.

The generics manifesto shows two features that are requested from generic protocols.

The first feature is needed to reuse the same protocol multiple types like struct A : Proto<B>, Proto<C>.

With SE–0142 we can actually achieve this behavior by creating new protocols and set a subset of the associated types from its parent super protocol.

Now we can use this trick to solve the problem from above and create two new protocols and use them as we previously wanted struct A : ProtoB, ProtoC. While this is great and solves my issue I’d like to pitch a shortcut for this.

Protocols with associated types are kinda generic, but they still need SE–0142 to specify all the associated types.

How about making all protocols that contain associated types to also have a shortcut generic protocol that specifies all the associated type in its generic parameter list?

Some first bikeshedding:

protocol MyStringCollection : Collecntion where Iterator.Element == String, Index == Int {}

protocol Collection<ElementType, IndexType> : Collection {
     
    typealias Iterator.Element = ElementType
    typealias Index = IndexType
}
But instead of creating these types by yourself, the compiler would autogenerate these for any protocol that have a list of associated types. To prevent collision between protocol names like Collection vs. Collection<ParamList> one could automatically prefix the generated procols with Generic.

Collection will generate GenericCollection<Element, Index>

This would be a huge shortcut for the feature introduced in SE–0142.

What does the community think about this idea?

···

--
Adrian Zubarev
Sent with Airmail

Am 2. Dezember 2016 um 20:13:50, Charles Srstka (cocoadev@charlessoft.com) schrieb:

On Dec 2, 2016, at 12:34 PM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I just overlooked that the subsection about generic protocols was inside the Unlikely section.

The problem is that I need a way to refer to a function with a specific name. Plus the connection type has to have a specific API, like having a DispatchQueue and know the router object if there is any (sounds like a protocol right?!). The function reference should also keep the connection object alive with a strong reference.

associatedtype does not solve that problem for me.

I clearly see that generic protocols overlap with associatedtype but couldn’t we find a compromise here? For instance like Chris Lattner introduced generic type aliases without the ability of constants.

Why don’t we just use angle brackets to specify associated types? Protocols aren’t using them for anything anyway. Then you could:

if let someSequence as? Sequence<Iterator.Element == Int> { // do something }

which would form a nice parallel to the syntax for casting things to generic types.

Charles


(Anders) #11

This is called generalized existentials. It is included in the Generic Manifesto, has been discussed quite a few times with long email chains before, and spawned the change to the `protocol<>` syntax as kinda a precursor. It would be surprised if Swift 4 Phase 2 doesn't have it given its popularity.

Regards
Anders

···

On 2 Dec 2016, at 20:13, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 2, 2016, at 12:34 PM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I just overlooked that the subsection about generic protocols was inside the Unlikely section.

The problem is that I need a way to refer to a function with a specific name. Plus the connection type has to have a specific API, like having a DispatchQueue and know the router object if there is any (sounds like a protocol right?!). The function reference should also keep the connection object alive with a strong reference.

associatedtype does not solve that problem for me.

I clearly see that generic protocols overlap with associatedtype but couldn’t we find a compromise here? For instance like Chris Lattner introduced generic type aliases without the ability of constants.

Why don’t we just use angle brackets to specify associated types? Protocols aren’t using them for anything anyway. Then you could:

if let someSequence as? Sequence<Iterator.Element == Int> { // do something }

which would form a nice parallel to the syntax for casting things to generic types.

Charles

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


(Tino) #12

Why don’t we just use angle brackets to specify associated types? Protocols aren’t using them for anything anyway.

You normally don't want to specify all associated types that way — if you had to, Array<T> would be declared like

struct Array<T>: SomeSequenceProtocol<T, IndexingIterator<Array<T>>, CountableRange<T>…>, ...

In C++, I have seen such things in the wild, and it's really no fun to work with such code.
Maybe it is feasible to think about that approach when generics support named parameters with default values, but in general, associated types and generics have different use cases.

if let someSequence as? Sequence<Iterator.Element == Int> { // do something }

hey, is this a try to silently establish a shortcut for if-let assignment? :wink:


(Daniel Leping) #13

Love it. I have one concern, though. How do we resolve conflicting
associated types once several protocols get applied to a class or a struct?

···

On Sat, 3 Dec 2016 at 11:00 Adrian Zubarev via swift-evolution < swift-evolution@swift.org> wrote:

I think I might found a solution that will satisfy generic protocols and
not break the system.

The generics manifesto shows two features that are requested from generic
protocols.

The first feature is needed to reuse the same protocol multiple types like struct
A : Proto<B>, Proto<C>.

With SE–0142 we can actually achieve this behavior by creating new
protocols and set a subset of the associated types from its parent super
protocol.

Now we can use this trick to solve the problem from above and create two
new protocols and use them as we previously wanted struct A : ProtoB,
ProtoC. While this is great and solves my issue I’d like to pitch a
shortcut for this.

Protocols with associated types are kinda generic, but they still need
SE–0142 to specify all the associated types.

How about making all protocols that contain associated types to also have
a shortcut generic protocol that specifies all the associated type in its
generic parameter list?

Some first bikeshedding:

protocol MyStringCollection : Collecntion where Iterator.Element == String, Index == Int {}

protocol Collection<ElementType, IndexType> : Collection {

    typealias Iterator.Element = ElementType
    typealias Index = IndexType
}

But instead of creating these types by yourself, the compiler would
autogenerate these for any protocol that have a list of associated types.
To prevent collision between protocol names like Collection vs.
Collection<ParamList> one could automatically prefix the generated
procols with Generic.

Collection will generate GenericCollection<Element, Index>

This would be a huge shortcut for the feature introduced in SE–0142.

What does the community think about this idea?

--
Adrian Zubarev
Sent with Airmail

Am 2. Dezember 2016 um 20:13:50, Charles Srstka (cocoadev@charlessoft.com)
schrieb:

On Dec 2, 2016, at 12:34 PM, Adrian Zubarev via swift-evolution < > swift-evolution@swift.org> wrote:

I just overlooked that the subsection about generic protocols was inside
the *Unlikely* section.

The problem is that I need a way to refer to a function with a specific
name. Plus the connection type has to have a specific API, like having a
DispatchQueue and know the router object if there is any (sounds like a
protocol right?!). The function reference should also keep the connection
object alive with a strong reference.

associatedtype does not solve that problem for me.

I clearly see that generic protocols overlap with associatedtype but
couldn’t we find a compromise here? For instance like Chris Lattner
introduced generic type aliases without the ability of constants.

Why don’t we just use angle brackets to specify associated types?
Protocols aren’t using them for anything anyway. Then you could:

if let someSequence as? Sequence<Iterator.Element == Int> { // do
something }

which would form a nice parallel to the syntax for casting things to
generic types.

Charles

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


(Adrian Zubarev) #14

I believe generic protocols could be used as a shortcut for protocols with associated types.

// Protocol with associated type

protocol Foo {
     
    associatedtype F
    func foo(_ f: F)
}

// Existential
typealias IntFoo = Any<Foo> where F == Int

struct Test : IntFoo {} // error

struct Test : Foo { func foo(_: Int) {…} }

let intFoo: IntFoo = Test() // fine

// SE-0142

protocol IntFooProtocol : Foo where F == Int {}

// Generic protocols
// Autogenerated with all associated types present in the parameter list

protocol GenericFoo<F> : Foo { … }
Instead of creating new protocol for a different subset of types constrained by the where clause, this approach could come really handy.

Does it affect stdlib and/or ABI somehow? When SE–0142 is implemented to improve the stdlib, wouldn’t that mean that more types like IntFooProtocol from above will spawn?

···

--
Adrian Zubarev
Sent with Airmail

Am 3. Dezember 2016 um 13:47:13, Anders Ha (hello@andersio.co) schrieb:

This is called generalized existentials. It is included in the Generic Manifesto, has been discussed quite a few times with long email chains before, and spawned the change to the `protocol<>` syntax as kinda a precursor. It would be surprised if Swift 4 Phase 2 doesn't have it given its popularity.

Regards
Anders

On 2 Dec 2016, at 20:13, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 2, 2016, at 12:34 PM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I just overlooked that the subsection about generic protocols was inside the Unlikely section.

The problem is that I need a way to refer to a function with a specific name. Plus the connection type has to have a specific API, like having a DispatchQueue and know the router object if there is any (sounds like a protocol right?!). The function reference should also keep the connection object alive with a strong reference.

associatedtype does not solve that problem for me.

I clearly see that generic protocols overlap with associatedtype but couldn’t we find a compromise here? For instance like Chris Lattner introduced generic type aliases without the ability of constants.

Why don’t we just use angle brackets to specify associated types? Protocols aren’t using them for anything anyway. Then you could:

if let someSequence as? Sequence<Iterator.Element == Int> { // do something }

which would form a nice parallel to the syntax for casting things to generic types.

Charles

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


(Daniel Leping) #15

Ok. Let's say I have a generic protocol P<T> with two methods:
func foo()
func bar(o:T)

I have a default implementation of foo, which internally calls bar.

How would work foo once a class implements P<Int> and P<String>?

···

On Sat, 3 Dec 2016 at 15:26 Adrian Zubarev via swift-evolution < swift-evolution@swift.org> wrote:

I believe generic protocols could be used as a shortcut for protocols with
associated types.

// Protocol with associated type

protocol Foo {

    associatedtype F
    func foo(_ f: F)
}

// Existential
typealias IntFoo = Any<Foo> where F == Int

struct Test : IntFoo {} // error

struct Test : Foo { func foo(_: Int) {…} }

let intFoo: IntFoo = Test() // fine

// SE-0142

protocol IntFooProtocol : Foo where F == Int {}

// Generic protocols
// Autogenerated with all associated types present in the parameter list

protocol GenericFoo<F> : Foo { … }

Instead of creating new protocol for a different subset of types
constrained by the where clause, this approach could come really handy.

Does it affect stdlib and/or ABI somehow? When SE–0142 is implemented to
improve the stdlib, wouldn’t that mean that more types like IntFooProtocol
from above will spawn?

--
Adrian Zubarev
Sent with Airmail

Am 3. Dezember 2016 um 13:47:13, Anders Ha (hello@andersio.co) schrieb:

This is called generalized existentials. It is included in the Generic
Manifesto, has been discussed quite a few times with long email chains
before, and spawned the change to the `protocol<>` syntax as kinda a
precursor. It would be surprised if Swift 4 Phase 2 doesn't have it given
its popularity.

Regards
Anders

On 2 Dec 2016, at 20:13, Charles Srstka via swift-evolution < > swift-evolution@swift.org> wrote:

On Dec 2, 2016, at 12:34 PM, Adrian Zubarev via swift-evolution < > swift-evolution@swift.org> wrote:

I just overlooked that the subsection about generic protocols was inside
the *Unlikely* section.

The problem is that I need a way to refer to a function with a specific
name. Plus the connection type has to have a specific API, like having a
DispatchQueue and know the router object if there is any (sounds like a
protocol right?!). The function reference should also keep the connection
object alive with a strong reference.

associatedtype does not solve that problem for me.

I clearly see that generic protocols overlap with associatedtype but
couldn’t we find a compromise here? For instance like Chris Lattner
introduced generic type aliases without the ability of constants.

Why don’t we just use angle brackets to specify associated types?
Protocols aren’t using them for anything anyway. Then you could:

if let someSequence as? Sequence<Iterator.Element == Int> { // do
something }

which would form a nice parallel to the syntax for casting things to
generic types.

Charles

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

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


(Adrian Zubarev) #16

This is a different problem that protocols have today. There was some talk about having some sort of keyword like implements to disambiguate which from where the implementation comes from.

Just pretend for a second, we wouldn’t have generic protocols and implement it the SE–01242 way:

protocol Foo {

   associatedtype T
   func foo()
   func bar(o: T)
}

protocol IntFoo : Foo where T == Int {}
protocol StringFoo : Foo where T == String {}

// Where do you want your extension?
extension Foo {
     
     func foo() {
          // cannot call bar from here, we don't know what T is
     }
}

extension Foo where T == String {
     func foo() {
          self.bar(o: "works fine") // calls a function that accepts a String
     }
}

extension Foo where T == Int {
     func foo() {
          self.bar(o: 42) // calls a function that accepts an Int
     }
}

class MyClass : IntFoo, StringFoo {
     // implement bar for Int and String
     // foo is problematic here already, and we haven't talked about generic protocols yet
}
See it’s not the problem of the generic protocols but the overlapping function foo of different protocols IntFoo and StringFoo.

In general Foo<T> would have the same problem. It should be solved in a different way, which is not part of this pitch.

···

--
Adrian Zubarev
Sent with Airmail

Am 3. Dezember 2016 um 15:07:03, Daniel Leping (daniel@crossroadlabs.xyz) schrieb:

Ok. Let's say I have a generic
protocol P<T> with two methods:

func foo()

func bar(o:T)

I have a default implementation of foo, which internally calls
bar.

How would work foo once a class implements P<Int> and
P<String>?

On Sat, 3 Dec 2016 at 15:26 Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:
I believe generic protocols could be used as a shortcut for protocols with associated types.

// Protocol with associated type

protocol Foo {
      
    associatedtype F
    func foo(_ f: F)
}

// Existential
typealias IntFoo = Any<Foo> where F == Int

struct Test : IntFoo {} // error

struct Test : Foo { func foo(_: Int) {…} }

let intFoo: IntFoo = Test() // fine

// SE-0142

protocol IntFooProtocol : Foo where F == Int {}

// Generic protocols
// Autogenerated with all associated types present in the parameter list

protocol GenericFoo<F> : Foo { … }
Instead of creating new protocol for a different subset of types constrained by the where clause, this approach could come really handy.

Does it affect stdlib and/or ABI somehow? When SE–0142 is implemented to improve the stdlib, wouldn’t that mean that more types like IntFooProtocol from above will spawn?

--
Adrian Zubarev
Sent with Airmail

Am 3. Dezember 2016 um 13:47:13, Anders Ha (hello@andersio.co) schrieb:

This is called generalized existentials. It is included in the Generic Manifesto, has been discussed quite a few times with long email chains before, and spawned the change to the `protocol<>` syntax as kinda a precursor. It would be surprised if Swift 4 Phase 2 doesn't have it given its popularity.

Regards
Anders

On 2 Dec 2016, at 20:13, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 2, 2016, at 12:34 PM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I just overlooked that the subsection about generic protocols was inside the Unlikely section.

The problem is that I need a way to refer to a function with a specific name. Plus the connection type has to have a specific API, like having a DispatchQueue and know the router object if there is any (sounds like a protocol right?!). The function reference should also keep the connection object alive with a strong reference.

associatedtype does not solve that problem for me.

I clearly see that generic protocols overlap with associatedtype but couldn’t we find a compromise here? For instance like Chris Lattner introduced generic type aliases without the ability of constants.

Why don’t we just use angle brackets to specify associated types? Protocols aren’t using them for anything anyway. Then you could:

if let someSequence as? Sequence<Iterator.Element == Int> { // do something }

which would form a nice parallel to the syntax for casting things to generic types.

Charles

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


(Adrian Zubarev) #17

If I’m not mistaken here, extension Foo where T == Int will have an error of redeclaration foo anyways.

···

--
Adrian Zubarev
Sent with Airmail

Am 3. Dezember 2016 um 15:22:56, Adrian Zubarev (adrian.zubarev@devandartist.com) schrieb:

extension Foo where T == Int {
     func foo() {
          self.bar(o: 42) // calls a function that accepts an Int
     }
}


(Daniel Leping) #18

In general I'm very positive with the idea of generic protocols. This
discussion is more about syntactic sugar, though I really like where it
goes.

Off topic:
IMO, we should revisit approaches others already use for conflicts
resolution. I personally tend to get something similar to Scala traits.
Should fit POT smoothly and naturally.

···

On Sat, 3 Dec 2016 at 16:30 Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:

If I’m not mistaken here, extension Foo where T == Int will have an error
of redeclaration foo anyways.

--
Adrian Zubarev
Sent with Airmail

Am 3. Dezember 2016 um 15:22:56, Adrian Zubarev (
adrian.zubarev@devandartist.com) schrieb:

extension Foo where T == Int {
     func foo() {
          self.bar(o: 42) // calls a function that accepts an Int
     }
}


(Adrian Zubarev) #19

There is one thing that I want to point out with pitched syntactic sugar. GenericMyProtocolName<U> will also let you reuse T within a generic type, where currently we cannot nest protocols into types. Even if we could, it’s not clear if nested declarations like protocol MyTProtocolName : MyProtocolName where U == T would be possible, so that T from the outer generic type is accessible.

Autogenerating the only possible generic protocols from protocols with associated types as a syntactic sugar to reduce spawning of types like IntFoo (as previously showed) seems reasonable to me. It does not break the current protocol system, but solves the first generic protocol feature from the generics manifesto.

There are still a few more questioned to answer:

How dow we want the generated parameter list to look like?
Can we drop Generic prefix without collisions?
Does this syntactic sugar improves the stdlib or affect ABI?
There are probably some more questions I cannot foresee by myself. Feel free to jump in the discussion. :wink:

PS: Yes this syntactic sugar does create an alternative way of creating ‘kinda’ the same protocol twice, but it reuses the pattern more naturally.

protocol Foo { associatetype Inner : SomeOtherProtocol }

// Assuming String and Int conforms to SomeOtherProtocol
protocol StringFoo : Foo where Inner == String {}
protocol IntFoo : Foo where Inner == Int {}

// VS.

// autogenerated
procotol GenericFoo<Inner : SomeOtherProtocol> : Foo { … }

// usage
GenericFoo<String>
GenericFoo<Int>

// or
typealias StringFoo = GenericFoo<String>
typealias IntFoo = GenericFoo<Int>

···

--
Adrian Zubarev
Sent with Airmail

Am 3. Dezember 2016 um 16:43:43, Daniel Leping (daniel@crossroadlabs.xyz) schrieb:

In general I'm very positive with
the idea of generic protocols. This discussion is more about
syntactic sugar, though I really like where it goes.

Off topic:

IMO, we should revisit approaches others already use for conflicts
resolution. I personally tend to get something similar to Scala
traits. Should fit POT smoothly and naturally.

On Sat, 3 Dec 2016 at 16:30 Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:
If I’m not mistaken here, extension Foo where T == Int will have an error of redeclaration foo anyways.

--
Adrian Zubarev
Sent with Airmail

Am 3. Dezember 2016 um 15:22:56, Adrian Zubarev (adrian.zubarev@devandartist.com) schrieb:

extension Foo where T == Int {
     func foo() {
          self.bar(o: 42) // calls a function that accepts an Int
     }
}


(Daniel Leping) #20

@Adrian, my comments inline below. Hope this helps.

There is one thing that I want to point out with pitched syntactic sugar.
GenericMyProtocolName<U> will also let you reuse T within a generic type,
where currently we cannot nest protocols into types. Even if we could, it’s
not clear if nested declarations like protocol MyTProtocolName :
MyProtocolName where U == T would be possible, so that T from the outer
generic type is accessible.

Autogenerating the only possible generic protocols from protocols with
associated types as a syntactic sugar to reduce spawning of types like
IntFoo (as previously showed) seems reasonable to me. It does not break
the current protocol system, but solves the first generic protocol feature
from the generics manifesto.

There are still a few more questioned to answer:

   - How dow we want the generated parameter list to look like?

The most obvious thing is to do something like Foo<Alias1 = Int, Alias2 =
. Otherwise we'll have to add some sort of associatedtype sorting

before; which doesn't sound good and just adds more complexity. Any other
options?

   - Can we drop Generic prefix without collisions?

I'm pretty sure we could just use existing protocols. All the namings can

be compiler generated as a function from protocol and arguments.

   - Does this syntactic sugar improves the stdlib or affect ABI?

Don't see any implications. Assuming current stdlib doesn't use the

feature. It's rather an addition than change.

There are probably some more questions I cannot foresee by myself. Feel
free to jump in the discussion. :wink:

PS: Yes this syntactic sugar does create an alternative way of creating
‘kinda’ the same protocol twice, but it reuses the pattern more naturally.

protocol Foo { associatetype Inner : SomeOtherProtocol }

// Assuming String and Int conforms to SomeOtherProtocol
protocol StringFoo : Foo where Inner == String {}
protocol IntFoo : Foo where Inner == Int {}

// VS.

// autogenerated
procotol GenericFoo<Inner : SomeOtherProtocol> : Foo { … }

// usage
GenericFoo<String>
GenericFoo<Int>

// or
typealias StringFoo = GenericFoo<String>
typealias IntFoo = GenericFoo<Int>

// The usage I propose is just do

typealias StringFoo = Foo<Inner = String>

//also in an inheritance like this:
class FooClass : Foo<Inner = String>, Foo<Inner = Int> {
//My question here is, though: how do we access Inner from FooClass

//Like this?
typealias InnerInt = Foo<Inner = String>.Inner
}

···

On Sat, Dec 3, 2016 at 6:22 PM, Adrian Zubarev < adrian.zubarev@devandartist.com> wrote:

--
Adrian Zubarev
Sent with Airmail

Am 3. Dezember 2016 um 16:43:43, Daniel Leping (daniel@crossroadlabs.xyz)
schrieb:

In general I'm very positive with the idea of generic protocols. This
discussion is more about syntactic sugar, though I really like where it
goes.

Off topic:
IMO, we should revisit approaches others already use for conflicts
resolution. I personally tend to get something similar to Scala traits.
Should fit POT smoothly and naturally.

On Sat, 3 Dec 2016 at 16:30 Adrian Zubarev <adrian.zubarev@devandartist. > > wrote:

If I’m not mistaken here, extension Foo where T == Int will have an
error of redeclaration foo anyways.

--
Adrian Zubarev
Sent with Airmail

Am 3. Dezember 2016 um 15:22:56, Adrian Zubarev (
adrian.zubarev@devandartist.com) schrieb:

extension Foo where T == Int {
     func foo() {
          self.bar(o: 42) // calls a function that accepts an Int
     }
}