Default Implementation in Protocols

Personally, I am against adding it to the language.

We've worked hard in the standard library codebase to move towards code that keeps struct declarations as short and simple as possible, moving implementations into extensions with logical groupings – usually protocol conformances. Yes, this takes a little extra code to break out the extensions, but the result is much clearer. Being able to structure code like this was a major motivation in the changes to private visibility.

The reason for this is to keep code you need to keep in your head to understand it to a minimum, and not have to go hunting for answers scattered throughout a struct declaration. The key question (for an implementor – users should be looking at generated interfaces) when looking at a struct is "what is this thing? what are its fundamental stored properties? What's the basic (maybe internal) way to create one?". Then you look at its protocol conformances and ask "how does this type conform to this protocol?". In each case, you are looking at hopefully less than a screenful of text. Sometimes that's a stretch but it's the goal.

I feel the same about protocols. At a glance, I should be able to look at a protocol and ask "what is the fundamental nature of this protocol?". I shouldn't have to scroll, or store too information in my head, to grok what the fundamentals of the protocol are: its inherited protocols, some associated types, and the basic customization points. That is it. Stuffing the implementation code in there as well would be actively harmful to this.

It also weakens the important distinction between customization points and regular extensions. There is a key difference between a method that appears in a protocol, and a method that is just an extension. When teaching a new Swift programmer about this distinction, the fact that the method is declared in two places seems like a feature, not a bug. For most useful protocols, which have non-customization point extensions or constrained default implementations, you will still need to write extensions. Allowing methods that happen to be customization points to be defined inside the body of the protocol seems odd. I fear adding this feature will degenerate into too many methods being defined in protocols, whether they need to be customization points or not.

It's unclear what the motivation is here. DRY, I guess, in that you don't need to restate the method signatures. That's a typing reduction, but hopefully one that becomes less important over time with better tooling. (in fairness, you could make the tooling argument as a reason it's OK to put bodies in the declaration, because folding). Typos in default implementations are a risk, but one this only partly mitigates rather than eliminates — I'd prefer solutions like requiring an implements keyword or generating near-miss warnings.

38 Likes