Sent from my iPhone

> On Sep 10, 2016, at 2:26 PM, Maximilian Hünenberger <m.huenenber...@me.com> 
> wrote:
> 
> 
> 
>> Am 12.08.2016 um 04:39 schrieb Douglas Gregor via swift-evolution 
>> <swift-evolution@swift.org>:
>> 
>> 
>> 
>> Sent from my iPhone
>> 
>>> On Aug 4, 2016, at 2:36 AM, Haravikk via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>> 
>>>>> On 4 Aug 2016, at 03:19, Brent Royal-Gordon via swift-evolution 
>>>>> <swift-evolution@swift.org> wrote:
>>>>> 
>>>>> On Aug 3, 2016, at 10:17 AM, Manav Gabhawala via swift-evolution 
>>>>> <swift-evolution@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 doesn't really have any features that stop working across modules. 
>> We're okay with the programmer having to think more and be more explicit 
>> across module boundaries (since it is API design at that point), but it'd 
>> take a very strong argument to have different runtime semantics across 
>> module boundaries. 
>> 
>> FWIW, I'm planning to write a complete proposal for conditional conformances 
>> and will start posting drafts once it is far enough along to be useful. It 
>> won't have support for protocols conforming to other protocols, though. 
>> 
>>   - Doug
>> 
> 
> Hi Doug,
> 
> When can we expect your proposal?

Within the next few weeks, I hope. 

  - Doug

> 
> Best regards
> Maximilian
> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to