<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 Jun 29, 2016, at 1:51 AM, Douglas Gregor <<a href="mailto:dgregor@apple.com" class="">dgregor@apple.com</a>> 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=""> associatedtype DetailID: PathParameterInitializable = UpdateID</div><div class=""> associatedtype UpdateID: PathParameterInitializable</div><div class=""> associatedtype DestroyID: PathParameterInitializable = UpdateID</div><div class=""><br class=""></div><div class=""> associatedtype CreateInput: StructuredDataInitializable = UpdateInput</div><div class=""> associatedtype UpdateInput: StructuredDataInitializable</div><div class=""><br class=""></div><div class=""> associatedtype ListOutput: StructuredDataFallibleRepresentable = UpdateOutput</div><div class=""> associatedtype CreateOutput: StructuredDataFallibleRepresentable = UpdateOutput</div><div class=""> associatedtype DetailOutput: StructuredDataFallibleRepresentable = UpdateOutput</div><div class=""> associatedtype UpdateOutput: StructuredDataFallibleRepresentable</div><div class=""><br class=""></div><div class=""> func list() throws -> [ListOutput]</div><div class=""> func create(element: CreateInput) throws -> CreateOutput</div><div class=""> func detail(id: DetailID) throws -> DetailOutput</div><div class=""> func update(id: UpdateID, element: UpdateInput) throws -> UpdateOutput</div><div class=""> func destroy(id: DestroyID) throws</div><div class="">}</div><div class=""><br class=""></div><div class="">extension ResourceController {</div><div class=""> public func list() throws -> [ListOutput] {</div><div class=""> throw ClientError.notFound</div><div class=""> }</div><div class=""><br class=""></div><div class=""> public func create(element: CreateInput) throws -> CreateOutput {</div><div class=""> throw ClientError.notFound</div><div class=""> }</div><div class=""><br class=""></div><div class=""> public func detail(id: DetailID) throws -> DetailOutput {</div><div class=""> throw ClientError.notFound</div><div class=""> }</div><div class=""><br class=""></div><div class=""> public func update(id: UpdateID, element: UpdateInput) throws -> UpdateOutput {</div><div class=""> throw ClientError.notFound</div><div class=""> }</div><div class=""><br class=""></div><div class=""> public func destroy(id: DestroyID) throws {</div><div class=""> throw ClientError.notFound</div><div class=""> }</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=""> public typealias CreateInput = NotTodo</div><div class=""> public typealias UpdateInput = NotTodo</div><div class=""><br class=""></div><div class=""> public typealias ListOutput = NotTodo</div><div class=""> public typealias CreateOutput = NotTodo</div><div class=""> public typealias DetailOutput = NotTodo</div><div class=""> public typealias UpdateOutput = NotTodo</div><div class=""><br class=""></div><div class=""> public typealias DetailID = NotString</div><div class=""> public typealias UpdateID = NotString</div><div class=""> public typealias DestroyID = NotString</div><div class=""><br class=""></div><div class=""> public func list() throws -> [Todo] {</div><div class=""> ...</div><div class=""> }</div><div class=""><br class=""></div><div class=""> public func create(element todo: Todo) throws -> Todo {</div><div class=""> ...</div><div class=""> }</div><div class=""><br class=""></div><div class=""> public func detail(id: String) throws -> Todo {</div><div class=""> ...</div><div class=""> }</div><div class=""><br class=""></div><div class=""> public func update(id: String, element todo: Todo) throws -> Todo {</div><div class=""> ...</div><div class=""> }</div><div class=""><br class=""></div><div class=""> public func destroy(id: String) throws {</div><div class=""> ...</div><div class=""> }</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></body></html>