<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="">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 class=""><br class=""></div><div class=""><br class=""><div class=""><br class=""><div><blockquote type="cite" 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 style="font-size:13px" class="">this is an example where concision is overrated</span>".</div></div><div class=""><div class=""><br class=""></div><div class=""><span style="" 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.<br class=""></div><div class=""><br class=""></div></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Sat, Jun 11, 2016 at 10:47 AM, John McCall via swift-evolution <span dir="ltr" class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">> On Jun 10, 2016, at 2:22 PM, Austin Zheng via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class="">
><br class="">
> Hello swift-evolutioneers,<br class="">
><br class="">
> Here's an idea. It's technically additive, but it's small and I think it fits in well with Swift 3's goals, one of which is to establish API conventions.<br class="">
><br class="">
> Right now, you can declare a function, type member, etc and mark it using "@available(*, unavailable, renamed:"someNewName()")". Doing so causes a compile-time error if the user tries to use that member, and if you provide the new name a fix-it is even generated telling you to use the new name.<br class="">
><br class="">
> However, you can (and still need to) provide an implementation (e.g. function body). You can just stick a fatalError() inside and be done with it, but my question is, is an impl even necessary?<br class="">
><br class="">
> My pitch is very simple: the declaration of any member marked with @available(*, unavailable), or in other words marked as unavailable regardless of platform or version, should be allowed to omit the implementation.<br class="">
><br class="">
> So, instead of:<br class="">
><br class="">
> @available(*, unavailable, renamed:"someNewAPI()")<br class="">
> public func someOldAPI() -> Int { fatalError() }<br class="">
><br class="">
> You can just have:<br class="">
><br class="">
> @available(*, unavailable, renamed:"someNewAPI()")<br class="">
> public func someOldAPI() -> Int<br class="">
><br class="">
> The intent is, in my opinion, clearer for the latter and it feels less kludgy.<br class="">
><br class="">
> What do people think? Are there any potential barriers (implementation or semantics) that would preclude this?<br class="">
<br class="">
</span>I actually just consider it a bug that you're require to implement an always-unavailable function. We can take it through evolution anyway, though.<br class="">
<br class="">
John.<br class="">
<br class="">
><br class="">
> Best,<br class="">
> Austin<br class="">
<div class="HOEnZb"><div class="h5">><br class="">
> _______________________________________________<br class="">
> swift-evolution mailing list<br class="">
> <a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
> <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
<br class="">
_______________________________________________<br class="">
swift-evolution mailing list<br class="">
<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="">
</div></div></blockquote></div><br class=""></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></div></div></div></body></html>