<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><br><br>Sent from my iPad</div><div><br>On Apr 15, 2016, at 6:17 PM, Douglas Gregor &lt;<a href="mailto:dgregor@apple.com">dgregor@apple.com</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8"><br class=""><div><blockquote type="cite" class=""><div class="">On Apr 15, 2016, at 4:15 PM, Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div dir="auto" class=""><div class=""><br class=""><br class="">Sent from my iPad</div><div class=""><br class="">On Apr 15, 2016, at 6:03 PM, Douglas Gregor &lt;<a href="mailto:dgregor@apple.com" class="">dgregor@apple.com</a>&gt; wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Apr 15, 2016, at 3:55 PM, Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</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 Apr 13, 2016, at 11:42 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=""><blockquote type="cite" 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 class="Apple-interchange-newline">On Apr 11, 2016, at 10:30 AM, Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>&gt; wrote:<br class=""><br class=""><br class=""><br class="">Sent from my iPad<br class=""><br class=""><blockquote type="cite" class="">On Apr 11, 2016, at 12:15 PM, Joe Groff via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""><br class=""><blockquote type="cite" class="">On Apr 7, 2016, at 5:12 PM, Douglas Gregor via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class="">One could perhaps work around (a), (b), and (d) by allowing compound (function-like) names like tableView(_:viewFor:row:) for properties, and work around (c) by allowing a method to satisfy the requirement for a read-only property, but at this point you’ve invented more language hacks than the existing @objc-only optional requirements. So, I don’t think there is a solution here.<br class=""></blockquote><br class="">To me, compound names for closure properties and satisfying property requirements with methods aren't hacks, they're missing features we ought to support anyway. I strongly prefer implementing those over your proposed solution. It sounds to me like a lot of people using optional protocol requirements *want* the locality of control flow visible in the caller, for optimization or other purposes, and your proposed solution makes this incredibly obscure and magical.<br class=""></blockquote><br class="">Do you have the same thought for optional closure properties? &nbsp;If so and heightForRow was an optional closure property it would satisfy all use cases elegantly. &nbsp;It could have a default implementation that returns nil. &nbsp;When non-uniform heights are required a normal method implementation can be provided. &nbsp;Delegates that have uniform row heights some of the time, but not all of the time, would also be supported by implementing the property.<br class=""></blockquote><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="">There are still some issues here:</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) It doesn’t handle optional read/write properties at all, because the setter signature would be different. Perhaps some future lens design would make this possible. For now, the workaround would have to be importing the setter as a second optional closure property, I guess. (The current system is similarly broken).</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 class=""><br class=""></div><div class="">I was only thinking about methods, not properties. &nbsp;:) &nbsp;How common are optional, writeable property requirements? &nbsp;I don’t have a good guess off the top of my head, but my hunch is that they are not that common. </div></div></div></div></blockquote><div class=""><br class=""></div><div class="">They are *very* rare. Aside from&nbsp;<a href="https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextInputTraits_Protocol/" class="">UITextInputTraits</a>,&nbsp;I see three in OS X and four in iOS.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><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="">2) For an @objc protocol, you won’t actually be able to fully implement the optional closure property with a property of optional type, because “return nil” in the getter is not the same as “-respondsToSelector: returns false”. Indeed, the getter result type/setter parameter type should be non-optional, so we would (at best) need a special rule that optional closure properties of @objc protocols can only be implemented by non-optional properties of closure type or by methods.</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 class=""><br class=""></div><div class="">This is related to why I asked about feasibility. &nbsp;I know that “return nil” is not that same as a “respondsToSelector:” implementation that returns false if the property was implemented to return nil. &nbsp;Some magic would need to handle that translation to make it work with existing Objective-C protocols. &nbsp;This would automate what I have done in Objective-C several times by implementing respondsToSelector manually to hide protocol method implementations when necessary. &nbsp;</div><div class=""><br class=""></div><div class="">The advantage of going this route is that Swift implementations of the legacy Cocoa protocols will still function as expected in Cocoa while fitting the Swift model much better than optional protocol requirements.</div></div></div></div></blockquote><br class=""></div><div class="">Both Joe’s suggestion and my proposal need hackery to do the right thing for Objective-C interoperability, and both are feasible. I feel like my proposal is more honest about the hackery going on :)</div></div></blockquote><div class=""><br class=""></div>Hmm. &nbsp;I agree that it's a little bit of hackers, but I don't think it's really dishonest to translate "return nil" into "respondsToSelector:" false and more than it is to make any other mapping from one system to another. &nbsp;<div class=""><br class=""></div><div class="">The main reason I prefer that approach is that it enables functionality that has been occasionally useful in Objective-C and is not otherwise possible in Swift - namely the ability to implement the protocol in a general purpose class and make a decision at initialization time whether you need a particular feature (such as dynamic row sizing) or not. &nbsp;Your approach doesn't allow for this.<br class=""></div></div></div></blockquote><br class=""></div><div>My approach requires you to use a different design—either split into multiple protocols (which is probably the best answer in most of these cases) or introduce a different kind of API contract. My claim is that these solutions are more natural in Swift than “check if a particular requirement was actually implemented”.</div></div></blockquote><div><br></div>I completely agree with you. &nbsp;However, unless Apple plans to do that with all of their frameworks over the next couple years it is not enough. &nbsp;We want Swift to play nice with the frameworks as they exist today, don't we?<div><br><blockquote type="cite"><div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>- Doug</div><div><br class=""></div><br class=""></div></blockquote></div></body></html>