<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 &lt;<a href="mailto:charlie@charliemonroe.net" class="">charlie@charliemonroe.net</a>&gt; 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 &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; 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.&nbsp;</span>&nbsp;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. &nbsp;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. &nbsp;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. &nbsp;I recognize that there are also use cases for a more relaxed attribute that just prohibits direct uses but still requires a function body. &nbsp;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. &nbsp;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>