[swift-evolution] [Swift 4.0] Conditional conformances via protocol extensions

Patrick Pijnappel patrickpijnappel at gmail.com
Fri Aug 5 05:59:57 CDT 2016


I'm not very familiar with the runtime so forgive me – the protocols would
only have to be added once right? And couldn't this usually be done at
compile time, or does it happen when the module is linked at startup?

On Thu, Aug 4, 2016 at 4:36 PM, Haravikk via swift-evolution <
swift-evolution at swift.org> wrote:

>
> > On 4 Aug 2016, at 03:19, Brent Royal-Gordon via swift-evolution <
> swift-evolution at swift.org> wrote:
> >
> >> On Aug 3, 2016, at 10:17 AM, Manav Gabhawala via swift-evolution <
> swift-evolution at swift.org> wrote:
> >>
> >> I was wondering why this would put any more of a burden on the runtime
> >> than simple inheritance of protocols. The way this could be
> >> implemented is to augment the ConformanceTable for nominal types by
> >> looking up its protocol extension’s inheritance clauses. I can
> >> definitely see this impacting compile time but I don’t see why runtime
> >> performance will be any different than simple inheritance. Further,
> >> cyclic chains can be detected and broken (compiler error) during the
> >> second pass of semantic analysis.
> >
> > My understanding—which may be incorrect, by the way—is that the issue is
> mainly with protocol extensions adding conformances, not specifically with
> those conformances being conditional, and that it specifically has to do
> with `is` and `as?` checks across module boundaries.
> >
> > Suppose you have these declarations in module M:
> >
> >       public protocol AProtocol {…}
> >       public protocol BProtocol: AProtocol {…}
> >       public protocol CProtocol {…}
> >
> >       // Public or otherwise doesn't matter here.
> >       public struct Foo: BProtocol {…}
> >
> > Foo essentially has a flat list of the protocols it conforms to attached
> to it. Notionally, you can think of that list as looking like:
> >
> >       Foo.self.conformsTo = [BProtocol.self, AProtocol.self]
> >
> > And when you write `foo is CProtocol`, that eventually translates into:
> >
> >       foo.dynamicType.conformsTo.contains(CProtocol.self)
> >
> > For a `Foo`, since the `conformsTo` list doesn't include
> `CProtocol.self`, it returns `false`.
> >
> > Now imagine that you write a new module, N, and in it you say:
> >
> >       extension Foo: CProtocol {…}
> >
> > You have now retroactively conformed `Foo` to `CProtocol`. Swift needs
> to reach into module M and add `CProtocol.self` to the
> `Foo.self.conformsTo` list. This is perfectly doable for a concrete
> type—it's one flat list, after all.
> >
> > Instead, though, imagine that module N extended `AProtocol` to add a
> conformance:
> >
> >       extension AProtocol: CProtocol {…}
> >
> > There are two ways to handle this. One is to find all types conforming
> to `AProtocol`, recursively, and add `CProtocol.self` to their conformance
> list. The other is to scrap the flat list of conformances and instead make
> `is` and `as?` recursively search each protocol. Either way, you have
> replaced a fast, flat operation with a slow, recursive one.
> >
> > Conditional conformance adds another wrinkle to this, of course—you must
> not only recursively search the list, but also evaluate the condition to
> see if it applies in this case. But the general problem of having to
> replace a fast search with a slow search applies either way.
>
> Great explanation! This switch from flat to recursively searched though
> seems like it would only occur when the extension is in an external module
> though; for internal modules would it not still be possible to determine
> the flat list for each type? In that case extending a type from another
> module could be either disallowed, or produce a warning to indicate the
> performance implication?
>
> The feature would still be very useful even just for internal use after
> all. Also it seems useful on a relatively small number of types, and the
> number of external modules that need/want to do this must narrow that even
> further, so external extensions may be quite niche, i.e- not worth losing
> the feature for internal use if that is indeed easier?
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160805/44f7fcb0/attachment.html>


More information about the swift-evolution mailing list