protocol extensions - default implementations vs. helper methods

So, this: http://nomothetis.svbtle.com/the-ghost-of-swift-bugs-future


Let me know if there's an existing thread about this, I searched the history but couldn't find any.


I understand more or less how this works, what I don't understand is why it has to work this way. Was this some kind of technical limitation or is it that this just makes more sense this way (even though it will be terribly confusing and will be a source of bugs and StackOverflow posts)?


The post says that:


> This time, the result, which is the same, might actually surprise the author of

callM2
very much. After all
m2
is not defined in the original protocol
A
. So if they chose to call it, it must be because they expected the specific implementation of the extension.


Why? If I call any method on any object, I expect it to choose the most specific version of that method available for the actual class of the object. If I override any method in my class, regardless where it came from, I expect this version of the method to always be called, because it might have some crucial information about this specific subclass. If I override e.g. viewDidLoad in my UIViewController subclass, it's essential that this specific overridden viewDidLoad will be called every time, and not any parent's implementation, because otherwise some of my object's properties would be uninitialized.


So what's so different about that m2 method that the author of callM2 expects it to always be called in the original version, even if I can write a better implementation of m2 that takes into account the details of my class?

I think we need to realize that the people who work on Swift understand that, while inheritance and protocol implementation can't solve the model of self-as-many-things, they can't divulge that they're solving that problem, and that they're giving us band-aids via protocols in the meantime. It's not worth their time to get this right, if it's going to be disallowed in a year.


If that doesn't make sense, a basic problem that Swift doesn't solve yet is that an object, to be able to model reality, must be able to call different code, with the same method signature. But when doing so, it must be clear which. Casting doesn't model the problem correctly. Delegates and other helper objects don't model the problem correctly. We're moving towards a place where segmentation of functionality will allow these methods, but we don't have syntax for it yet. Protocols, and this as-yet-unnamed concept, are stepping on each others' toes in the meantime.

I agree that you would always expect to get the most specific implementation of a method or property.

IOW you always want dynamic dispatch even though this probably forces the compiler to add a switch on all types conforming to the protocol to the assembly.


I have a case where I unpack and repack heterogeneous data. After losing a long battle to avoid the switch in unpacking I am happy to let the compiler do the switch for the packing.

I doubt if this bug pointed out in the link can or should happen. After all it says nowhere in the Swift Programming Guide that you can declare and define methods or properties in a protocol extension. You can only provide default implementations in an extension. If the compiler lets this go through then the docs are unclear.

Jan E.

It gets a little clearer if you understand that the relationship between methods in the protocol extension and methods in the conforming type is NOT inheritance. It's something new — call it "replacement" or something. This seems bizarre until you realize that protocol extensions are available for struct types as well as class types, and struct types do not have subclassing/inheritance. If conforming types were able to override protocol extension methods, then the subclassing mechanism would be effectively extended to struct types, which presumably is never going to happen.


The difference of behavior between extension methods that appear as protocol requirements and ones that don't is explicitly documented, so you may not like it but it is what it is.


However there is one horrible bug in the current implementation (bug #21470728). If you have a subclass of a class that adopts the protocol but the class does not provide its own version of a not-required method defined in the protocol extension (whew, sorry!), then a subclass implementation of that method isn't used from other protocol extension methods. That is to say, the "replacement" mechanism operates only on the top-level conforming class, not subclasses.

protocol extensions - default implementations vs. helper methods
 
 
Q