[swift-evolution] Overriding protocol default implementation

Rod Brown rodney.brown6 at icloud.com
Fri Feb 10 21:54:22 CST 2017



Sent from my iPhone

> On 11 Feb 2017, at 2:20 pm, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
> 
>> On Fri, Feb 10, 2017 at 6:59 PM, Rod Brown <rodney.brown6 at icloud.com> wrote:
>> I don't believe these two worlds are in conflict at all.
>> 
>> We currently have the default only state (without overrides), plus a conflict. We would simply be adding "override" functionality in part to clear the conflict.
>> 
>> With POP the idea is that the protocol, in knowing about how it is constituted, has a clear pattern for how it implements its behaviours. Therefore you can leverage the protocol to bear the brunt of the work, just as we do now.
>> 
>> The additional tweak to the design of protocols is to allow a user to define their own implementation where the default is not appropriate, or is incomplete for the use case.
> 
> I think I've written a poor explanation of my point. In Swift, it is the library _author_, not the _user_, who gets the final say as to the upper limits on what users can do with the author's types, by using modifiers such as `final` and `open` (or the lack thereof). This has been the subject of vehement opposition but, nonetheless, it is a clear and opinionated decision on the part of the language. What you are critiquing as a bug is regarded as a feature. That is to say, it is a way for the author of a protocol extension method to deny to the user a customization point (in other words, to disallow the outright overriding of the "default" behavior).
>  
>> This doesn't work against POP - it simply observes that implementations at times may need to be customised to the use case, and allows that, as an optional override.
> 
> Again, the status quo in Swift is that it is up to the protocol's author to determine which methods are overridable by the user and which are not. The idea is that protocol extension methods that are not protocol requirements are the intended way for disallowing such overriding.
> 
> As to its practical use: this guarantees that if protocol `P` has a method `foo()`, it is possible to invoke `foo()` on an instance of existential type `P` knowing that you will invoke the intended method. A concrete type `T` that conforms to `P` may have its own `foo()` with totally different semantics. After all, if `foo()` is not a protocol requirement, then conforming types can have their own `foo()` do anything at all, with the collision in name being mere coincidence and no guarantee of similar semantics. And, with extensions, some third party can implement such a `foo()` on `T` that the library author has no way of reasoning about. By having a "shadowing" feature for `foo()`, I can know that no matter how anyone in the future extends type `T`, I will invoke the intended `foo()` with the right semantics on an instance of existential type `P`.
>  
>> It's clear people are trying to do this already because they already have overrides that are causing this conflict, and thus we are having the discussion.
> 
> It sounds like what you are saying is that users of libraries are trying to "override" protocol extension methods that authors of libraries have designed not to be overridden. That this causes problems is, afaict, the intended consequence of this feature and not an overlooked bug. For maximum flexibility, however, Swift allows you to "shadow" the non-overridable method with an identically named method of your own design that can have different semantics.

If the intent is to restrict users and to provide the power to the author of the protocol, it appears not just opinionated, but arrogant.

As software developers, we need to work together to provide solutions to use cases. This includes not understanding what some use case may be. But instead, the consistent argument here has been that software should be as it is designed, to hell with the users of the frameworks who may have an unknown use case.

This therefore has created the shadow problem, where people implementing a protocol end up colliding with the same name, and must make casts back.

Why can't we make an adjustment and allow protocol implementers to define the cases where the protocol action is inappropriate.

I believe this argument stems back to the closed-by-default argument on classes with "public" and shows a concerning trend in how Swift is being developed. We cannot look at Swift purely from the perspective of the Standard Library, or one framework, or one implementer. It is how we coordinate between framework authors that we end up creating a unified system.

It should never be a feature to make users of frameworks fight with writers of frameworks. That's just absurd.

>  
>> In this case, I don't see overriding the protocol "default" as working against this world - I think it clarifies it.
>> 
>> Rod
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170211/a1b1fff7/attachment.html>


More information about the swift-evolution mailing list