<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Jun 12, 2016, at 9:08 PM, Charlie Monroe <<a href="mailto:charlie@charliemonroe.net" class="">charlie@charliemonroe.net</a>> wrote:</div><div class=""></div></blockquote><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="">On Jun 11, 2016, at 3:51 AM, Andrew Bennett via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Unavailable doesn't mean un-callable.<div class=""><div class=""><ul class=""><li class="">If you're marking an override or required initialiser as unavailable, it's still possible it's called dynamically, or by super.</li><li class="">If you're marking it unavailable for some OS versions, it could still be called by the other OS versions.</li><li class="">If it's neither of those two categories, you probably don't even need the function declaration.</li></ul></div><div class="">It's not clear what default behaviour you would want in an unavailable method, calling super, calling a new method, a runtime error, ...<br class=""></div><div class=""><br class=""></div><div class="">An undefined implementation lacks clarity, as Erica says, "<span class="" style="font-size: 13px;">this is an example where concision is overrated</span>".</div></div><div class=""><div class=""><br class=""></div><div class=""><span class="">Likewise, as Brent says, you may want the old unavailable API to call through to the new API. </span> A new version of a library may be dynamically linked by something compiled against an older version.</div></div></div></div></div></blockquote></div></div></div></div></div></blockquote><div><br class=""></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">As Andrew says - I have several cases where I mark a method on a subclass as unavailable to ensure subclasses do not call it directly, but it is required by the root class to be implemented (which it is and gets called).<div class=""><br class=""></div><div class="">Example:</div><div class=""><br class=""></div><div class="">class Root {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func doSomething() {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>print("Root")</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div class="">}</div><div class=""><br class=""></div><div class="">class Subclass {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>@available(*, unavailable)</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>override func doSomething() {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>super.doSomething()</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>print("Subclass")</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<span class="Apple-tab-span" style="white-space: pre;">        </span></div><div class="">}</div><div class=""><br class=""></div><div class="">And you can still do:</div><div class=""><br class=""></div><div class="">let instance: Root = Subclass()</div><div class="">instance.doSomething()</div><div class=""><br class=""></div><div class="">and it will call Root Subclass.<br class=""><div class=""><br class=""></div><div class="">If it's renamed, you should really first deprecate it and just call the new API and after a while make it unavailable with no change in the code.</div><div class=""><br class=""></div><div class="">If it's meant for abstract classes, then it's kind of a different issue.</div></div></div></div></blockquote><div><br class=""></div></div><div>In many of the cases you guys are describing, we ought to have enough information to do the right thing. For example, library evolution shouldn't be done with an ordinary unavailable attribute; it should use something that indicates that the API was added in v2.6c, deprecated in v2.7, and made illegal in v2.8. With that information, we clearly would still require a function body if the build configuration says that we need to support pre-v2.8 clients.</div><div><br class=""></div><div>My point was just that there is a clear use case for an attribute that says "don't allow this declaration to be used at all", including indirectly such as via a protocol requirement or overridden method, and those use cases should not require an actual function body. I recognize that there are also use cases for a more relaxed attribute that just prohibits direct uses but still requires a function body. Perhaps that should just be a completely different attribute, or perhaps we can differentiate based on the attribute arguments, or perhaps we can address all of those use cases with targeted language features. However, we should still get to a point where we don't require function bodies for the true-unavailable cases.</div><div><br class=""></div><div>John.</div></body></html>