<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="">On Jan 9, 2016, at 4:05 PM, Brent Royal-Gordon via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><div><blockquote type="cite" class=""><br class="Apple-interchange-newline"><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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="">From my previous thread, "[Draft Proposal] Require `final` on protocol extension members", I'm getting the sense that many people want straight-up dynamic dispatch from protocol extension methods. That is, protocol extension methods should be treated as if they were included as requirements of the protocol; the implementations provided should be treated as overridable defaults.</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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="">A few questions about that:</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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;" class=""><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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="">1. Do people really want this?</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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;" class=""></div></blockquote><div><br class=""></div><div>I do. There are lots of useful things you could do with dynamically dispatched protocol extension methods that you cannot easily do elegantly. As an example, I could declare this extension on ErrorType:</div><div><br class=""></div><div>extension ErrorType {</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>var isFileNotFoundError: Bool {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>// Check for all of the possible “File not found” errors in POSIXError, NSCocoaError, NSURLError, NSOSStatusErrorDomain, etc.</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>// Then check for NSUnderlyingErrorKey and if it exists, rinse and repeat with that.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>func toNSError() -> NSError {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>return self as NSError</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div>}</div><div><br class=""></div><div>A method like this allows one to do things like this:</div><div><br class=""></div><div>do {</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>try NSFileManager.defaultManager().removeItemAtURL(someURL)</div><div>} catch {</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>if error.isFileNotFoundError {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>// The file we were trying to delete didn’t exist. Ignore the error</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>} else {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>// Okay, something actually went wrong</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>NSApp.presentError(error.toNSError())</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div>}</div><div><br class=""></div><div>Then, perhaps you define your own error type that has a FileNotFound error condition in it, and would like to override these methods:</div><div><br class=""></div><div>enum MyErrorType: ErrorType {</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>case FileNotFound(url: NSURL)</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>// more cases</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>var isFileNotFoundError: Bool {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>// Unfortunately, this will never get called.</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>return case .FileNotFound(_) = self</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>func toNSError() -> NSError {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>// This won’t get called either. The user will see a lovely “MyErrorType error (Int)” instead of our localized error message.</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">                </span>switch self {</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>case let .FileNotFound(url: url):</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>let userInfo = [NSLocalizedFailureReasonErrorKey : String(format: NSLocalizedString(“FNF %@“, comment: “String format: File Not Found error”), url.lastPathComponent)]</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>return NSError(domain: “MyErrorType”, code: 1, userInfo: userInfo)</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>// other cases</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>}</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div>}</div><div><br class=""></div><div>For any of the above to work as is, each and every error handler has to do an as? check against every custom error type in your project.</div><div><br class=""></div><div>Charles</div><div><br class=""></div></div></body></html>