[swift-evolution] [Pitch] Overridable Members in Extensions

Jordan Rose jordan_rose at apple.com
Thu Feb 18 12:07:03 CST 2016

[Proposal: https://github.com/jrose-apple/swift-evolution/blob/overridable-members-in-extensions/proposals/nnnn-overridable-members-in-extensions.md <https://github.com/jrose-apple/swift-evolution/blob/overridable-members-in-extensions/proposals/nnnn-overridable-members-in-extensions.md>]

> On Feb 18, 2016, at 5:13 , Andrew Bennett <cacoyi at gmail.com> wrote:
> Sounds interesting, I know I've wanted to do similar, and had some weird bugs.
> Many of my concerns have been discussed already, I've added a few more below:
> I'm also a little concerned about the potential for unexpected side-effects from methods called by the original class, *this* seems to break the principle of "least astonishment", you're less likely to know the base classes implementation than that of your extension.
> Other points worth considering:

Good questions! I'll answer them here but also update the document later today.
> Can methods be marked as final, or something else if it's unsafe to override?
Yep, `final` should work just like it does today.

> What about methods marked as inline, called by the super-class, is this unexpected?
Inlining is discussed in great depth in the Library Evolution doc <http://jrose-apple.github.io/swift-library-evolution/>, but the relevant points are that marking something inlineable doesn't guarantee it'll be inlined, and that you can't inline a call unless you know the dynamic type of the receiver (and therefore know which override will be called).

> If most people only want this for testing should it only be allowed on classes imported with @testable (only restrict this with (unsafe) ObjC classes?).
I know of at least one non-testing use case that I probably can't share, so let's just say I don't think we need to artificially limit the feature. (It's at least no worse than Objective-C.)

What we could do is say that methods in extensions of classes you don't own are @nonobjc by default, and that you have to opt into making them @objc. What do you think?

> You probably want to swap/replace the implementation rather than just override it for testing.
That's out of scope for this proposal. If you're interested in this, I'd suggest coming up with a version of 'dynamic' that works for all Swift methods, not just @objc ones, and then further annotating that as "but only for testing".

> I'm presuming that this will not allow you to swap out one implementation for another? If not then it may be necessary to be able to call or refer to the original version of the method.

This is only for subclass-overriding, not ObjC-category-style method replacement.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160218/b88f6c81/attachment.html>

More information about the swift-evolution mailing list