<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=""><div class="">Hi Austin,</div><div class=""><br class=""></div>I’m sorry to say, but this proposal makes me really sad. &nbsp;I consider associated type inference one of the more elegant aspects of Swift. &nbsp;It would be very unfortunate to lose it. &nbsp;<div class=""><br class=""></div><div class="">I am really pleased to see that Dmitri has offered an alternative that looks very reasonable. &nbsp;I’m hoping the Doug or Chris (or someone else from the core team) can chime in on the feasibility of this alternative. &nbsp;If it is considered viable and Dmitri isn’t able to write the proposal I would be happy to do so.<div class=""><br class=""></div><div class="">If the alternative isn’t viable and we must proceed with a proposal to remove inference I think there is one crucial thing to consider that isn’t discussed in this proposal: retroactive modeling. &nbsp;As far as I can tell, this proposal will *prohibit* some types from conforming to some protocols. &nbsp;Specifically, if a type defines a typealias with a name that matches the name of an associatedtype in a protocol it would not be possible to retroactively model that protocol. &nbsp;Because of the name conflict an associatedtype declaration would not be allowed and the existing typealias would not meet the requirement. &nbsp;Consider this example:</div><div class=""><br class=""></div><div class="">// Module A</div><div class="">public struct S {</div><div class="">&nbsp; &nbsp; public typealias Foo = Int</div><div class="">}</div><div class=""><br class=""></div><div class="">// Module B</div><div class="">public protocol P {</div><div class="">&nbsp; &nbsp; associatedtype Foo</div><div class="">}</div><div class=""><br class=""></div><div class="">// Module C</div><div class="">import A</div><div class="">import B</div><div class=""><br class=""></div><div class="">// compiler error: `S` does not meet the `Foo` associatedtype requirement</div><div class="">extension S : P {</div><div class="">&nbsp; &nbsp; // compiler error: cannot define associatedtype `Foo` for `S` which already declares typealias `Foo`</div><div class="">&nbsp; &nbsp; associatedtype Foo = String</div><div class="">}</div><div class=""><br class=""></div><div class="">I cannot support any proposal that breaks retroactive modeling in this way.</div><div class=""><br class=""></div><div class="">Another item that is not mentioned in this proposal is that typealias is not the only way to meet an associatedtype requirement in the language today. &nbsp;For example, this code is legal:</div><div class=""><br class=""></div><div class="">protocol&nbsp;Foo {<br class="">&nbsp; &nbsp;&nbsp;associatedtype&nbsp;Bar<br class="">}<br class="">struct&nbsp;S :&nbsp;Foo&nbsp;{<br class="">&nbsp; &nbsp;&nbsp;struct&nbsp;Bar {}<br class="">}</div><div class=""><br class=""></div><div class="">If we *must* drop inference I prefer the alternative of just doing that: dropping inference, but otherwise leaving things alone. &nbsp;All associated type requirements would need to be explicitly satisfied using one of the mechanisms that is currently valid for satisfying a non-inferred associated type requirement. &nbsp;The ability to satisfy these requirements in a variety of ways is a *benefit* that provides valuable flexibility.</div><div class=""><br class=""></div><div class=""><div class="">I agree that something should look for a good solution to the subclass typealias issue, but I don’t think this is it. &nbsp;Ideally we would find a solution that works well in the presence of retroactive modeling making code such as the following valid:</div><div class=""><br class=""></div><div class="">// module A</div><div class="">protocol&nbsp;P1 {<br class="">&nbsp; &nbsp;&nbsp;associatedtype&nbsp;Foo</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;@infers(Foo)<br class="">&nbsp; &nbsp;&nbsp;var&nbsp;foo: Foo {&nbsp;get&nbsp;}<br class="">}</div><div class="">// module B<br class="">protocol&nbsp;P2 {<br class="">&nbsp; &nbsp;&nbsp;associatedtype&nbsp;Foo</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; @infers(Foo)<br class="">&nbsp; &nbsp;&nbsp;func&nbsp;bar() -&gt; Foo<br class="">}<br class=""><br class="">// module C<br class="">class&nbsp;Base {<br class="">&nbsp; &nbsp;&nbsp;let&nbsp;foo:&nbsp;String&nbsp;=&nbsp;"foo"<br class="">}<br class="">class&nbsp;Derived :&nbsp;Base&nbsp;{<br class="">&nbsp; &nbsp;&nbsp;func&nbsp;bar() -&gt;&nbsp;Int&nbsp;{&nbsp;return&nbsp;42&nbsp;}<br class="">}</div></div><div class=""><br class=""></div><div class="">// module D</div><div class="">import A</div><div class="">import B</div><div class="">import C</div><div class="">import D</div><div class="">extension Base : P1 {}</div><div class="">extension Derived : P2 {}</div><div class=""><br class=""></div><div class="">We don’t always control the protocol or type definitions we want to make work together. &nbsp;The ability to make code that “should work together” actually do so with minimal fuss is one of the great things about Swift. &nbsp;Any time we interfere with retroactive modeling we increase the need for boilerplate adapter types, etc.</div><div class=""><br class=""></div><div class="">One detail appears to be implied by the proposal but isn’t explicitly stated. &nbsp;Specifically, it looks like the intent is that other than only being valid when used to meet a protocol requirement, associatedtype otherwise works like a typealias. &nbsp;It would be good to have this behavior clarified if the proposal moves forward.</div><div class=""><br class=""></div><div class="">-Matthew</div><div class=""><br class=""></div><div class=""><br class=""><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jun 25, 2016, at 12:50 AM, Austin Zheng via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; 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:&nbsp;<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 class=""><br class=""></div><div class="">Best,</div><div class="">Austin</div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></div></div></div></body></html>