[swift-evolution] [Draft Proposal] Require `final` on protocol extension members

Brent Royal-Gordon brent at architechies.com
Tue Jan 5 22:18:44 CST 2016

> I think that it is a larger change, but if we’re going to change this, shouldn’t we do it right?

Okay, so let's sketch out a "doing it right" solution here. No implementation details, just high-level ideas.

If you want members added in extensions to be overridable, that basically means you want them to add requirements to the protocol and then provide a default implementation of those requirements. In other words, you're reducing the distinction between the protocol and its extensions. This is a goal of several other planned changes as well, such as letting you provide default implementations directly in a protocol definition.

I think it's fair to say that the ultimate goal here is to erase the distinction between the protocol definition and its extensions as much as possible. Now, it's probably not possible to make them completely equivalent, because you can't allow an extension to break an existing conformance. So, for instance, you probably can't put a requirement in an extension unless you provide a default implementation. But this is not very different from, for instance, not being able to declare stored properties in concrete type extensions.

So, if our ultimate goal is to, as much as possible, erase the distinction between protocol declarations and protocol extensions, without changing existing behavior, what are the changes needed? At a minimum, they are:

1. Add `final` protocol members, and migrate current protocol extension members to `final` members.
2. Add an error when a `final` protocol member conflicts with a conforming type's member.
3. Permit default implementations in the main protocol definition.
4. Permit protocol extensions to add conformances to other protocols (with all the `where` clause bells and whistles).
5. Allow protocol extensions to add requirements with default implementations.

I put them in this order because I think this is the order they should be implemented in. 1 should come first because if it comes after 5, the exact same source code can compile in two adjacent versions of Swift with different semantics. I think we need to avoid this so that people can get used to the new semantics. 2 needs to come early as well, both to justify the use of `final` as the keyword, and to provide additional safety as the definitions of protocols become more diffuse and fragmented. 3 and 4 I put before 5 simply because I think they're most likely easier to implement.

So in short, I think that even if you want to change protocol extensions to add defaulted requirements, this proposal is a necessary first step. The Swift development process encourages incremental development, with each step in implementing a change refining the language in a useful way. I think this is the step we should take right now. If it's the only change we ever make in this direction, it will still be an improvement in the language; if we take further steps, they will benefit from having this change already implemented.

Brent Royal-Gordon

More information about the swift-evolution mailing list