<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 7 Feb 2017, at 06:18, Slava Pestov <<a href="mailto:spestov@apple.com" class="">spestov@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On Feb 6, 2017, at 9:12 PM, Karl Wagner <<a href="mailto:razielim@gmail.com" class="">razielim@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 7 Feb 2017, at 06:05, Slava Pestov <<a href="mailto:spestov@apple.com" class="">spestov@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><blockquote type="cite" class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class=""><br class="Apple-interchange-newline">On Feb 6, 2017, at 9:00 PM, Karl Wagner via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><pre class="" style="word-wrap: break-word; white-space: pre-wrap;">- Nested protocols in generic types are not parameterised by the parent's generic parameters.</pre></div></div></blockquote><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">So if I write GenericType<Int>.SomeProto and GenericType<String>.SomeProto, is it the same protocol? What about GenericType.SomeProto, is that allowed?</div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">Slava</div></div></blockquote></div><br class=""><div class="">GenericType.SomeProto (without parameters) is the only spelling that is allowed. There is no GenericType<Int>.SomeProto.</div><div class=""><br class=""></div><div class="">That way we avoid every bound-generic type creating a new protocol. </div><div class="">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.</div><div class=""><br class=""></div><div class="">- Karl</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><pre class="" style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal; color: rgb(51, 51, 51);"><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">class</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">MyCollectionView</span><<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">MediaItem</span>> : <span class="pl-e" style="box-sizing: border-box; color: rgb(121, 93, 163);">UICollectionView </span>{
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">protocol</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">Source</span> {
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);"><span class="pl-c" style="box-sizing: border-box;">//</span> [implicit] associatedtype MediaItem</span>
</pre></div></div></div></blockquote><div class=""><br class=""></div><div class="">I’m worried this is going to be tricky to implement; we definitely won’t get this with the initial implementation of nested protocol types.</div></div></div></blockquote><div><br class=""></div><div>Do you mean that unparameterised protocols would be tricky to implement, or that capturing and implicit associated types would be? Because the latter isn’t part of the proposal - just sketching out how a capturing solution _might_ look.</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><pre class="" style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal; color: rgb(51, 51, 51);"><span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);"></span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">item</span>(<span class="pl-smi" style="box-sizing: border-box;"><span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">at</span></span>: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Int</span>) <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">-></span> MediaItem
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">var</span> numberOfItems<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Int</span> { <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">get</span> }
}
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">var</span> source<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Any</span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>MyCollectionView.<span class="pl-smi" style="box-sizing: border-box;">Source</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">where</span> .<span class="pl-smi" style="box-sizing: border-box;">MediaItem</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">==</span> MediaItem<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span> <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);"><span class="pl-c" style="box-sizing: border-box;">//</span> Not possible today.</span>
</pre></div></div></div></blockquote><div class=""><br class=""></div>I think for this use-case, it makes sense to allow the protocol itself to be parametrized.</div></div></blockquote><div><br class=""></div><div>I used to think so, but your comments on the PR and working through some examples made me prefer this way. I think it’s exactly what we mean when we say that associated types are preferred to generic protocols. It also means that adding or removing generic types from the parent does not affect the nested protocol in any way - it could still be mangled the same for ABI compatibility and spelled the same for source compatibility.</div><div><br class=""></div><div>The syntax is not exactly ideal. I’m using the Any<...> syntax because I think it’s a bit easier to understand in the context of this discussion, but that’s already gone from the language, so really it would look closer to:</div><div><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><div><font face="Courier" class="">var source: Source where .MediaItem == MediaItem</font></div><div><br class=""></div></div></blockquote><div class="">Still not ideal. But then, we automatically infer generic type parameters inside a generic context. Maybe it would be reasonable to do the same in this context?</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class=""><font face="Courier" class="">extension Array where Element: Comparable {</font></div></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""><font face="Courier" class="">var reverseSorted: Array { //< inferred to be Array<T> by context</font></blockquote></div><div class=""><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""><font face="Courier" class="">return self.sorted(by: >)</font></blockquote></blockquote></div><div class=""><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""><font face="Courier" class="">}</font></blockquote></div><div class=""><div class=""><font face="Courier" class="">}</font></div></div></blockquote><div class=""><div class=""><div class=""></div></div></div><div class=""><br class=""></div>For capture-existentials, the analog may look something like:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Courier" class="">var source: Source // [implicit] where .MediaItem == MediaItem, exhaustively binding all captured types. May be over-specific.</font></div><div class=""><br class=""></div></blockquote><div class="">We would need a way to opt-out of that, though:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><font face="Courier" class="">var source: Source where _ // Make the existential less specific with an explicit ‘where’ clause.</font></div></blockquote><div class=""><br class=""></div><div class="">But none of that is part of the proposal. Again, just sketching what the situation might look like later if we took this approach. I’m curious to see what others feel about it.</div><div class=""><br class=""></div><div class="">- Karl</div><div class=""><br class=""></div><div class=""><div class=""><div><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Slava</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><pre class="" style="box-sizing: border-box; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13.600000381469727px; margin-top: 0px; margin-bottom: 0px; line-height: 1.45; word-wrap: normal; padding: 16px; overflow: auto; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; word-break: normal; color: rgb(51, 51, 51);"><span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);"></span>}
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">class</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">BookSource</span>: <span class="pl-e" style="box-sizing: border-box; color: rgb(121, 93, 163);">MyCollectionView</span>.<span class="pl-e" style="box-sizing: border-box; color: rgb(121, 93, 163);">Source </span>{
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">typealias</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">MediaItem</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> Book
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">item</span>(<span class="pl-smi" style="box-sizing: border-box;"><span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">at</span></span>: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Int</span>) <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">-></span> Book { <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);"><span class="pl-c" style="box-sizing: border-box;">/*</span> ... <span class="pl-c" style="box-sizing: border-box;">*/</span></span> }
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">var</span> numberOfItems<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Int</span> { <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);"><span class="pl-c" style="box-sizing: border-box;">/*</span> ... <span class="pl-c" style="box-sizing: border-box;">*/</span></span> }
}
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">class</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">DummySource</span><<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">MediaItem</span>>: <span class="pl-e" style="box-sizing: border-box; color: rgb(121, 93, 163);">MyCollectionView</span>.<span class="pl-e" style="box-sizing: border-box; color: rgb(121, 93, 163);">Source </span><span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">where</span> MediaItem<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> <span class="pl-e" style="box-sizing: border-box; color: rgb(121, 93, 163);">DummyConstructable</span> {
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);"><span class="pl-c" style="box-sizing: border-box;">//</span> associatedtype 'MediaItem' bound to generic parameter.</span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);"></span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">item</span>(<span class="pl-smi" style="box-sizing: border-box;"><span class="pl-en" style="box-sizing: border-box; color: rgb(121, 93, 163);">at</span></span>: <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Int</span>) <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">-></span> MediaItem { <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);"><span class="pl-c" style="box-sizing: border-box;">/*</span> ... <span class="pl-c" style="box-sizing: border-box;">*/</span></span> }
<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">var</span> numberOfItems<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">:</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">Int</span> { <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);"><span class="pl-c" style="box-sizing: border-box;">/*</span> ... <span class="pl-c" style="box-sizing: border-box;">*/</span></span> }
}
MyCollectionView<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Book<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span>().<span class="pl-smi" style="box-sizing: border-box;">source</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">BookSource</span>()
MyCollectionView<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Book<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span>().<span class="pl-smi" style="box-sizing: border-box;">source</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> DummySource<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Book<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span>()
MyCollectionView<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Song<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span>().<span class="pl-smi" style="box-sizing: border-box;">source</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">DummySource</span>() <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);"><span class="pl-c" style="box-sizing: border-box;">//</span> type is: DummySource<Song></span>
<span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);"></span>MyCollectionView<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);"><</span>Movie<span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">></span>().<span class="pl-smi" style="box-sizing: border-box;">source</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(167, 29, 93);">=</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 134, 179);">DummySource</span>() <span class="pl-c" style="box-sizing: border-box; color: rgb(150, 152, 150);"><span class="pl-c" style="box-sizing: border-box;">//</span> type is: DummySource<Movie></span></pre></div></div></div></blockquote></div></div></blockquote></div><br class=""></div></div></body></html>