<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="">I'm not sure this is a problem. Once you bind the associated types explicitly, the requirements using those associated types need to match the bound types otherwise the type checker will emit an error. If you have default associated types and default implementations, but then bind the associated types differently and do not update your type-specific implementations to use those other types, you will get an error message. This is how explicitly specifying associated types works today.</div><div class=""><br class=""></div><div class="">Austin</div><br class=""><div><blockquote type="cite" class=""><div class="">On Jun 28, 2016, at 10:17 PM, Paulo Faria 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=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 29, 2016, at 1:51 AM, Douglas Gregor &lt;<a href="mailto:dgregor@apple.com" class="">dgregor@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">which might reduce the common case for conforming to the protocol to be, e.g.,</span></div></blockquote></div><br class=""><div class="">Just discovered another horrible implication of type inference removal for the same use case. :OOO</div><div class=""><br class=""></div><div class="">This is the full code for the protocol</div><div class=""><br class=""></div><div class=""><div class="">public protocol ResourceController {</div><div class="">&nbsp; &nbsp; associatedtype DetailID: PathParameterInitializable = UpdateID</div><div class="">&nbsp; &nbsp; associatedtype UpdateID: PathParameterInitializable</div><div class="">&nbsp; &nbsp; associatedtype DestroyID: PathParameterInitializable = UpdateID</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; associatedtype CreateInput: StructuredDataInitializable = UpdateInput</div><div class="">&nbsp; &nbsp; associatedtype UpdateInput: StructuredDataInitializable</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; associatedtype ListOutput: StructuredDataFallibleRepresentable = UpdateOutput</div><div class="">&nbsp; &nbsp; associatedtype CreateOutput: StructuredDataFallibleRepresentable = UpdateOutput</div><div class="">&nbsp; &nbsp; associatedtype DetailOutput: StructuredDataFallibleRepresentable = UpdateOutput</div><div class="">&nbsp; &nbsp; associatedtype UpdateOutput: StructuredDataFallibleRepresentable</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; func list() throws -&gt; [ListOutput]</div><div class="">&nbsp; &nbsp; func create(element: CreateInput) throws -&gt; CreateOutput</div><div class="">&nbsp; &nbsp; func detail(id: DetailID) throws -&gt; DetailOutput</div><div class="">&nbsp; &nbsp; func update(id: UpdateID, element: UpdateInput) throws -&gt; UpdateOutput</div><div class="">&nbsp; &nbsp; func destroy(id: DestroyID) throws</div><div class="">}</div><div class=""><br class=""></div><div class="">extension ResourceController {</div><div class="">&nbsp; &nbsp; public func list() throws -&gt; [ListOutput] {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; throw ClientError.notFound</div><div class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; public func create(element: CreateInput) throws -&gt; CreateOutput {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; throw ClientError.notFound</div><div class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; public func detail(id: DetailID) throws -&gt; DetailOutput {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; throw ClientError.notFound</div><div class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; public func update(id: UpdateID, element: UpdateInput) throws -&gt; UpdateOutput {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; throw ClientError.notFound</div><div class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; public func destroy(id: DestroyID) throws {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; throw ClientError.notFound</div><div class="">&nbsp; &nbsp; }</div><div class="">}</div></div><div class=""><br class=""></div><div class="">Suppose we have an implementation like this:</div><div class=""><br class=""></div><div class=""><div class="">public struct TodoController : ResourceController {</div><div class="">&nbsp; &nbsp; public typealias CreateInput = NotTodo</div><div class="">&nbsp; &nbsp; public typealias UpdateInput = NotTodo</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; public typealias ListOutput = NotTodo</div><div class="">&nbsp; &nbsp; public typealias CreateOutput = NotTodo</div><div class="">&nbsp; &nbsp; public typealias DetailOutput = NotTodo</div><div class="">&nbsp; &nbsp; public typealias UpdateOutput = NotTodo</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; public typealias DetailID = NotString</div><div class="">&nbsp; &nbsp; public typealias UpdateID = NotString</div><div class="">&nbsp; &nbsp; public typealias DestroyID = NotString</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; public func list() throws -&gt; [Todo] {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; public func create(element todo: Todo) throws -&gt; Todo {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; public func detail(id: String) throws -&gt; Todo {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; public func update(id: String, element todo: Todo) throws -&gt; Todo {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div class="">&nbsp; &nbsp; }</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; public func destroy(id: String) throws {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div class="">&nbsp; &nbsp; }</div><div class="">}</div></div><div class=""><br class=""></div><div class="">Notice that the typealiases and the function declarations don’t match. But the compiler doesn’t complain because the protocol has default implementations in the protocol extension. This means that if the person implementing the protocol doesn’t make sure the types match exactly, there’s gonna be unexpected behaviour. Which I’m sure he/she will take quite some time to figure out. :(</div><div class=""><br class=""></div><div class=""><br class=""></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=""></body></html>