[swift-evolution] [RFC][Proposal] Ease restrictions on protocol nesting

Matthew Johnson matthew at anandabits.com
Tue Feb 7 09:10:43 CST 2017


> On Feb 6, 2017, at 11:12 PM, Karl Wagner via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
>> On 7 Feb 2017, at 06:05, Slava Pestov <spestov at apple.com <mailto:spestov at apple.com>> wrote:
>> 
>>> 
>>> On Feb 6, 2017, at 9:00 PM, Karl Wagner via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at 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 at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170207/ba58726a/attachment.html>


More information about the swift-evolution mailing list