[swift-evolution] Proposal: Split extensions into implementing methods and adding static functions Was: [swift-evolution-announce] [Review] SE-0164: Remove final support in protocol extensions

Xiaodi Wu xiaodi.wu at gmail.com
Wed May 3 05:10:27 CDT 2017


I should add, the reason final is inapt in this situation is at least
twofold.

The first is, of course, that this makes it impossible to guarantee source
compatibility and offer additional functionality in a protocol extension,
since any such addition would break unknowable amounts of existing code.
Consider if we wanted to add a commonly requested convenience function to
Collection in the standard library. Since it is so commonly useful and
doesn't currently exist in the standard library, it is very likely that
numerous people have written their own extensions for one or more concrete
types (say, Array). It would therefore not be possible to add this to the
standard library as an extension on Collection unless (a) we pick a silly
name that we know no one would call this function, which is
counterintuitive, as ideally we want to pick an obvious name that everyone
would call this function; or (b) we make it a protocol requirement with a
default implementation, which is both not what it really is (conceptually,
it's not something that all things need to do in order to be a bona fide
collection, for which we can give just a placeholder default; rather, it's
a neat thing that all bona fide collections can do, and we are implementing
the specific neat thing and not a placeholder to be refined later) and it
would run into the second issue.

The second issue to do with why final is inapt relates to the fact that
protocols are not hierarchically inherited but are meant to be composable
without the problems of multiple inheritance. For instance, the following
is possible--and should be:

```
protocol P {
}

extension P {
    func f() {
        print("42")
    }
}

protocol Q {
}

extension Q {
    func f() {
        print("43")
    }
}

struct S : P, Q {
}

let s = S()

(s as P).f()
(s as Q).f()
```

If f were either final or a protocol requirement, barriers would arise due
to clashing definitions. Again, this has source compatibility implications.
It also places limits on the composability and evolution of protocols where
today there aren't any.


On Wed, May 3, 2017 at 04:00 Xiaodi Wu <xiaodi.wu at gmail.com> wrote:

> Well, the revised integer protocols that were just approved do just that:
> some functions are defaults and others cannot be overridden. Smart shifts,
> for example, are deliberately not customization points. This is also the
> case for Equatable: you get to define ==, but != is not a protocol
> requirement and cannot be overridden. A very long list of algorithms on
> Sequence and Collection are also implemented in this way (contains,
> elementsEqual, enumerated, first, flatMap, lexicographicallyPrecedes, min,
> max, reduce, reversed, sorted...). So, at least equatables, numbers,
> sequences, and collections depend on this design--I'd call that pervasive.
> And these are just the protocols I've worked with in the last two days; I
> haven't even looked at the documentation for others.
>
> It serves a real purpose. As has been said before, protocols are not mere
> bags of syntax. However, the compiler cannot enforce arbitrary semantic
> requirements. This feature allows protocols to guarantee the semantics of
> particular members. It is how you can know with complete certainty while
> writing a generic algorithm that a == b implies !(a != b) for all equatable
> values. Conceptually, protocol extension methods are exactly what their
> name suggests: they are definitive implementations of generic algorithms
> that make use of the guarantees of a protocol; they are not placeholder
> implementations of a requirement that constitutes a part of the protocol
> itself. How else would you provide functionality that extends a protocol as
> you would a type?
>
> And no, we wouldn't prefer to just mark all of those members as "final".
> That was just settled in SE-0164; once upon a time, it was required to do
> so, but that was actually tried and backed out, and now the last vestiges
> of that legacy have literally just been slated for removal with community
> approval.
>
>
> On Wed, May 3, 2017 at 03:09 Brent Royal-Gordon <brent at architechies.com>
> wrote:
>
>> On May 3, 2017, at 12:25 AM, Xiaodi Wu via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> I definitely agree that it's a feature that _can_ be used unwisely, but
>> the fact remains that it _is_ used pervasively in the standard library, and
>> deliberately
>>
>>
>> I'm not so sure that's true. Which standard library protocols
>> intentionally depend upon certain parts to not be overridable? Are they so
>> pervasive that we wouldn't prefer to just mark those members that need it
>> with a `final` keyword? If John McCall woke up tomorrow with some genius
>> idea of how to make extension methods overridable with zero overhead, would
>> we choose to keep the current design?
>>
>> That's not to say the proposal at hand is a good idea, but I think you're
>> overselling the current design.
>>
>> --
>> Brent Royal-Gordon
>> Architechies
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170503/735aa8c3/attachment.html>


More information about the swift-evolution mailing list