[RFC][Proposal] Ease restrictions on protocol nesting


(Karl) #1

Anybody from core-team able to weigh in: do we want to keep this rule of not allowing parametrised protocols (in which case nesting is "trivial" - capturing is not allowed, only one protocol exists, so it's just namespacing), or is this something which should be deferred?
  
If possible I would like to include protocols inside of generic types. I kind of like the non-parameterised version. It's elegant and allows you to write generic conformers to the protocol.

···

  
On Feb 7, 2017 at 4:10 pm, <Matthew Johnson (mailto:matthew@anandabits.com)> wrote:
  
>
> On Feb 6, 2017, at 11:12 PM, Karl Wagner via swift-evolution <swift-evolution@swift.org (mailto:swift-evolution@swift.org)> wrote:
>
>
>
>
>
>
> >
> > On 7 Feb 2017, at 06:05, Slava Pestov <spestov@apple.com (mailto:spestov@apple.com)> wrote:
> >
> >
> >
> > >
> > >
> > > On Feb 6, 2017, at 9:00 PM, Karl Wagner via swift-evolution <swift-evolution@swift.org (mailto:swift-evolution@swift.org)> wrote:
> > >
> > >
> > > - Nested protocols in generic types are not parameterised by the parent's generic parameters.
> > >
> > >
> > >
> >
> > So if I write GenericType<Int>.SomeProto and GenericType<String>.SomeProto, is it the same protocol? What about GenericType.SomeProto, is that allowed?
> >
> >
> >
> > Slava
> >
> >
>
>
>
> GenericType.SomeProto (without parameters) is the only spelling that is allowed. There is no GenericType<Int>.SomeProto.
>
>
>
> That way we avoid every bound-generic type creating a new protocol.
>
>
>
  
I have only had a chance to scan the proposal so I will probably have more comments after I take a closer look, but I want to respond to this topic right away.
  
I understand the reason why you want it to work this way, but think it will be a significant source of confusion. Protocols will behave differently than any other entity nested in a generic type. This means the protocols nested in generic types will likely be counterintuitive for most people.
  
I know this was the case for me while I was scanning the proposal. I had to think carefully to understand how you want this to work and why you want this behavior. That is despite it being a relatively direct consequence of the Swift’s design for protocols, which uses associated types and intentionally does not allow generic protocols.
  
It may be that there isn’t a good way to avoid that and we need to try to address it through documentation and education. But I think this should receive careful consideration before we commit to this direction.
  
Overall the proposal looks really great! I’m really looking forward to this feature.
  
>
>
>
> I think it works really nicely when you consider what it would like like with existential-based capturing. Notice that there is only one ‘MyCollectionView.Source’, and compatibility is determined based on existential constraints.
>
>
>
> - Karl
>
>
>
>
>
>
> class MyCollectionView<MediaItem> : UICollectionView { protocol Source { // [implicit] associatedtype MediaItem func item(at: Int) -> MediaItem var numberOfItems: Int { get } } var source: Any<MyCollectionView.Source where .MediaItem == MediaItem> // Not possible today. } class BookSource: MyCollectionView.Source { typealias MediaItem = Book func item(at: Int) -> Book { /* ... */ } var numberOfItems: Int { /* ... */ } } class DummySource<MediaItem>: MyCollectionView.Source where MediaItem: DummyConstructable { // associatedtype 'MediaItem' bound to generic parameter. func item(at: Int) -> MediaItem { /* ... */ } var numberOfItems: Int { /* ... */ } } MyCollectionView<Book>().source = BookSource() MyCollectionView<Book>().source = DummySource<Book>() MyCollectionView<Song>().source = DummySource() // type is: DummySource<Song> MyCollectionView<Movie>().source = DummySource() // type is: DummySource<Movie>
>
>
>
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org (mailto:swift-evolution@swift.org)
> https://lists.swift.org/mailman/listinfo