<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 15 Nov 2016, at 16:46, Shawn Erickson <<a href="mailto:shawnce@gmail.com" class="">shawnce@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">This has been discussed somewhat heavily in the past and nothing yet has really moved forward on it. I do think a good way of doing something like this would be helpful. I have resulted to defining an interface with an extension that provides empty defaults and for each function a match bool var exists to imply if it exists or not. The code accepting a delegate can probe these bool vars to configure itself to efficiently operate based on knowledge about what the delegate expects (some missing from most proposed solutions other then @objc optional).<br class=""><div class="gmail_quote"><div dir="ltr" class="">On Tue, Nov 15, 2016 at 6:59 AM Karl via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On 15 Nov 2016, at 12:22, Haravikk via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br class="gmail_msg m_1374670648404452039Apple-interchange-newline"><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On 15 Nov 2016, at 07:53, Rick Mann via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br class="gmail_msg m_1374670648404452039Apple-interchange-newline"><div class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"><blockquote type="cite" class="gmail_msg">On Nov 14, 2016, at 22:51 , Charlie Monroe via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>> wrote:<br class="gmail_msg"><br class="gmail_msg">One major example is the NS/UITableViewDataSource or Delegate - there are many many methods that you don't need to implement, hence are optional.<br class="gmail_msg"><br class="gmail_msg">But I think that this was partially solved by default implementation of protocol methods, which pretty much does what you want...<br class="gmail_msg"></blockquote><br class="gmail_msg">I just realized I only responded to someone else, and not the whole list. It does, but it forces me to make the return value of the protocol method optional, so that the default implementation can return nil. <br class="gmail_msg"><br class="gmail_msg">In the end, I guess that's not so bad, since I'm not happy with the entire approach, but it'll do for now.<br class="gmail_msg"></div></div></blockquote></div><br class="gmail_msg"><div class="gmail_msg">What's different about having the method return nil vs being optional? You're attempting to call it either way, and presumably need some means of handling the return value, except in Swift it's all nice and explicit and easy to put in a conditional like:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><span class="gmail_msg m_1374670648404452039Apple-tab-span" style="white-space:pre-wrap">        </span>if let result = myObject.someOptionalMethod() { /* Do some stuff */ }</font></div><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><span class="gmail_msg m_1374670648404452039Apple-tab-span" style="white-space:pre-wrap">        </span>print(myObject.someOptionalStringMethod() ?? "")</font></div><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><br class="gmail_msg"></font></div>And so-on. If you need a method to be both optional, and return a nilable result then you can use a double optional like so:<div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><span class="gmail_msg m_1374670648404452039Apple-tab-span" style="white-space:pre-wrap">        </span>if let result = myObject.someDoubleOptionalMethod() { // Method was implemented</font></div><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><span class="gmail_msg m_1374670648404452039Apple-tab-span" style="white-space:pre-wrap">                </span>if let value = result { // Method returned a value</font></div><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><span class="gmail_msg m_1374670648404452039Apple-tab-span" style="white-space:pre-wrap">                        </span>/* Do some stuff */</font></div><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><span class="gmail_msg m_1374670648404452039Apple-tab-span" style="white-space:pre-wrap">                </span>}</font></div><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><span class="gmail_msg m_1374670648404452039Apple-tab-span" style="white-space:pre-wrap">        </span>}</font><br class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">By defining the methods as returning an Optional and throwing in default implementations you can specify fewer, bigger protocols and make clear what the requirements really are, though personally given the choice I'd prefer a dozen smaller protocols that are absolutely explicit in what they do.</div></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">But yeah, I think the tools you need are all there already; maybe there's an argument to be made for allowing default return values on protocol methods, to reduce the boiler-plate?</div></div>_______________________________________________<br class="gmail_msg">swift-evolution mailing list<br class="gmail_msg"><a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg"></div></blockquote><br class="gmail_msg"></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg">I think there is a difference between:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">- A method which returns an optional result, and</div><div class="gmail_msg">- An optional method which, if present, always returns a result</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Perhaps not so much of a difference at the usage site (it’s just a question of placing a ? for optional chaining), but semantically and when conforming to the protocol, they mean different things.</div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">- Karl</div><br class="gmail_msg"></div>_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div>
</div></blockquote><br class=""></div><div>If you don’t mind me asking, what is your use-case?</div><div><br class=""></div><div>Even though I think "optional methods" and “methods returning optionals” are different things, I don’t really have any examples where optional methods are better than sub-protocols.</div><br class=""><div class="">e.g.</div><div class=""><br class=""></div><div class="">```</div><div class="">// Core callbacks</div><div class="">protocol MyDelegate { }</div><div class=""><br class=""></div><div class="">// Optional callbacks, added like a mixin</div><div class="">protocol MyDelegateWithExtras : MyDelegate { }</div><div class=""><br class=""></div><div class="">// Some more optional callbacks</div><div class="">protocol MySubDelegate : MyDelegate {}</div><div class=""><br class=""></div><div class="">class DelegateImpl : MySubDelegate, MyDelegateWithExtras {</div><div class=""> // Implement all core + optional callbacks</div><div class="">}</div><div class=""><br class=""></div><div class="">var d : MyDelegate = DelegateImpl()</div><div class=""><br class=""></div><div class="">if let extras = d as? MyDelegateWithExtras {</div><div class=""> // invoke optional functionality</div><div class="">}</div><div class="">```</div><div class=""><br class=""></div><div class="">I don’t know what the overhead of the as? call is, but it’s almost certainly less than an Obj-C `respondsToSelector` call. Depending on whether you need to swap the delegate for objects of different types, you could also use generics to optimise the checks (and possibly more) away.</div><div class=""><br class=""></div><div class="">- Karl</div></body></html>