<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="">Thank you for your detailed feedback. Would it be helpful if I prepared a PR?<div class=""><br class=""></div><div class="">Austin</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jun 28, 2016, at 10:33 PM, Douglas Gregor <<a href="mailto:dgregor@apple.com" class="">dgregor@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jun 24, 2016, at 10:50 PM, Austin Zheng via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hello all,<div class=""><br class=""></div><div class="">Per Chris Lattner's list of open Swift 3 design topics (<a href="http://article.gmane.org/gmane.comp.lang.swift.evolution/21369" class="">http://article.gmane.org/gmane.comp.lang.swift.evolution/21369</a>), I've put together a proposal for removing type inference for associated types.</div><div class=""><br class=""></div><div class="">It can be found here: <a href="https://github.com/austinzheng/swift-evolution/blob/az-assoctypeinf/proposals/XXXX-remove-assoctype-inference.md" class="">https://github.com/austinzheng/swift-evolution/blob/az-assoctypeinf/proposals/XXXX-remove-assoctype-inference.md</a></div><div class=""><br class=""></div><div class="">Thoughts, criticism, and feedback welcome. There are at least two slightly different designs in the proposal, and I'm sure people will have ideas for even more.</div></div></div></blockquote><br class=""></div><div class="">Thanks for working on this. I have a couple of comments.</div><div class=""><br class=""></div><div class="">I don’t think we should be adding the ability to write ‘associatedtype’ declarations in classes/structs/enums. We already have the ability to explicitly state the associated type witness by declaring a typealias, struct, enum, or class with the appropriate name. Indeed, I feel like a lot of complexity of the proposal is linked to adding ‘associatedtype’ declarations into the language, and I’d rather this proposal stay narrow.</div><div class=""><br class=""></div><div class="">I think it’s important for this proposal to show the other ways in which one can get associated type witnesses without writing them explicitly in the conforming type, even once inference goes away. For example, we have associated type defaults, e.g.,</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>protocol P {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> associatedtype Associated = Int</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>struct X : P {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> // Associated becomes Int if not otherwise specified</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class=""><br class=""></div><div class="">and with typealiases in protocol extensions becoming real and useful, one could also use protocol extensions:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>protocol P2 {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> associatedtype Index</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>extension P2 {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> typealias Index = Int</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class=""><br class=""></div><div class="">which, of course, implies that one can use various tricks with constrained protocol extensions and such. There isn’t any proposed change here, but it illustrates that Swift programmers aren’t without recourse if type inference for associated types go away.</div><div class=""><br class=""></div><div class="">One concern with applying the above tricks is that existing code can change meaning when inference goes away. For example, let’s think about the “Iterator” type of a Sequence. It already uses default associated type witnesses (not associated type witness inference!) to give a default of IndexingIterator<Self>, e.g.,</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>protocol Sequence {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> associatedtype Iterator: IteratorType</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> func makeIterator() -> Iterator</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>protocol Collection : Sequence {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> associatedtype Iterator = IndexingIterator<Self></div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span> func makeIterator() -> Iterator // redeclaration helps inference</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}</div><div class=""><br class=""></div><div class="">When a type that conforms to Collection doesn’t provide makeIterator, it gets a default one via:</div><div class=""><br class=""></div><div class=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>extension Collection where Iterator == IndexingIterator<Self> {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> public func makeIterator() -> IndexingIterator<Self> { … }</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}</div><div class=""><br class=""></div><div class="">That will still work (yay). However, simply removing associated type inference means that a collection type that *does* provide makeIterator()—but not, directly, Iterator—would change behavior:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>struct IntCollection : Collection {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> typealias Element = Int</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span> func makeIterator() -> IntCollectionIterator { … }</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class=""><br class=""></div><div class="">With associated type inference, we infer Iterator = IntCollectionIterator and select IntCollection.makeIterator() to satisfy the makeIterator() requirement.</div><div class=""><br class=""></div><div class="">Without associated type inference, we use the default Iterator = IndexingIterator<Self> and select the makeIterator() from the protocol extension (because IntCollection.makeIterator() now returns the wrong type), which turns an error of omission into an unpleasant surprise. We might need something like near-miss checking for defaulted protocol requirements (which we discussed in the thread at <a href="http://thread.gmane.org/gmane.comp.lang.swift.devel/1799" class="">http://thread.gmane.org/gmane.comp.lang.swift.devel/1799</a>) to help find those surprises. They already exist today, of course, but removing associated type inference would make them worse.</div><div class=""><br class=""></div></div><div class="">Finally, one of the chief concerns is that we won’t be able to provide a nice experience when conforming to the standard library’s collection protocols. I would *love* to see some more thought to into how we can use the above tools to handle it, although I suspect the only way to do that is to implement some part of this proposal experimentally and see what it takes to get the standard library and it’s tests working again. How far can the tools above go toward reducing the need to specify various associated type witnesses in conforming types? What are the surprises?</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>- Doug</div><div class=""><br class=""></div><br class=""></div></div></blockquote></div><br class=""></div></body></html>