> Am 06.06.2016 um 22:13 schrieb L Mihalkovic <[email protected]>: > > >>> On Jun 6, 2016, at 9:34 PM, Douglas Gregor <[email protected]> wrote: >>> >>> >>> On Jun 6, 2016, at 12:12 PM, Thorsten Seitz <[email protected]> wrote: >>> >>> >>> >>> Am 06.06.2016 um 18:51 schrieb Douglas Gregor <[email protected]>: >>> >>>> >>>>> On Jun 5, 2016, at 3:24 AM, L. Mihalkovic via swift-evolution >>>>> <[email protected]> wrote: >>>>> >>>>> The issue is to decide on the applicability scope. Thinking 'my app/their >>>>> stuff' is an illusion. To the compiler & runtime there is only code split >>>>> into modules, some in source code and others as dylibs (.dll, .so, ...). >>>>> Any extension based conditional refines a protocol everywhere. What's >>>>> hard is to compute the complete effects of these changes predictably, >>>>> reliably and fast. Because when we consider 'but look, i have a single >>>>> small extension', the compiler&runtime must be ready to deal symetrically >>>>> with anything we throw at it. They can't start building 15 different ways >>>>> the compute the side effects based on many different scenarios because it >>>>> will be un-ruly code, and too complex to try to explain to us what we >>>>> will see. >>>>> The circular redefinitions case is one of the knightmares that hides in >>>>> there... would mean having to assign priority to scopes, when there is no >>>>> scopes yet. At the moment, the binary conformance table contains records >>>>> for 3 types of conformances. First step would be to add a new type to >>>>> match extension based conformance, and then record where it came from, >>>>> and add some priority scheme to be able to navigate any conformance >>>>> chain(remember that the pb grows everytime we decide 'oh cool, lets use a >>>>> Padleft module rather than write my own 15 lines to do it - see the >>>>> recent pb with nodejs). Not a simple task even with time, which they do >>>>> not have now. >>>>> >>>>> @core_team i know this is a coarse explanation, but hopefully at least in >>>>> the right ballpark. >>>> >>>> Roughly, yes. The specific problem regards answering the question “where >>>> must the runtime look to determine whether a given type X conforms to >>>> protocol P?”. Right now, the runtime conceptually needs to look: >>>> >>>> 1) Into a list of known protocol conformances for the type X, and >>>> 2) If X is a class type, the list of known protocol conformances for >>>> the superclass of X (recursively) >>>> >>>> If we add the ability for a protocol extension to add a conformance to >>>> another protocol, add to that: >>>> >>>> 3) Into the list of protocol extensions of other protocols Q that >>>> provide conformance to P >>> >>> So, the difference is that in the case >>> >>> protocol P { ... } >>> protocol Q : P { ... } >>> struct X : Q {...} >>> >>> X's list of known protocol conformances already contains Q and P, >>> whereas in the case >>> >>> protocol P { ... } >>> protocol Q { ... } >>> struct X : Q {...} >>> extension Q : P >>> >>> X's list of known protocol conformances just contains Q and is not extended >>> by P as a result of the extension? >>> Did I understand this right? >> >> Yes, that’s correct. >> >>> Is that (not being able to extend the conformance lists of all types as a >>> result of an extension) a restriction of having module boundaries? >> >> Effectively, yes: you can’t simply enumerate all of the cases because some >> other module might add a new types/protocol extensions/conformances. It has >> to be dynamically discoverable. > > yes… for each new module added to a known mix, the final conformances list > can be completely different.
But this is information known at compile time and does not have to be determined at runtime. An extension should be only effective in the module in which it is defined and in modules using that module. All of these get to know the extension at compile time. There should be no need to have extensions affect modules that do not see them. This should be similar to the Classboxes module system proposed for Smalltalk (http://scg.unibe.ch/research/classboxes) AFAIR. > >> >>> Or is it simply not feasible for other reasons? >> >> It’s feasible, in the sense that it can be implemented. The concern is that >> it’s potentially very expensive, and is very likely to introduce ambiguities >> where there are two different protocol conformances to satisfy the query “X >> conforms to P”. Ambiguities should have to be solved at compile time by the programmer. I'm not a fan of fancy ordering schemes e.g. for Mixins but prefer manual resolvement which makes it understandable what happens. Cecil from the University of Washington did that well (http://www.cs.washington.edu/research/projects/cecil/pubs/). > > that’s what I thought would motivate some sort of prioritization scheme.. but > I guess (or judge from experience with the static/dynsmic dispatch story with > extensions, or the so called ‘defender’ methods in java) anytime one scheme > is picked, there are people to question that it is the right one. Then I keep > circling back to the idea of being able to subdivide a module into separate > sections (call-em namespace or submodule) which would limit the scope of > conformance baring extensions. From a 10mile high view, I thought the the > current TEXT segments could be duplicated (one per namespace/submodule), > leaving the current one to be the de-facto module’s namespace. Granted it > would complicate the loading code, it would not destroy whole-module > optimization. Alternatively it would be nice if Xcode was retrofitted with a > simple support for creating quartz-like module-inside-module structures. But > either way, we circle back to defining a type hierarchy to simplify the > problem… which is usually summarized by layers as “do not ask a question for > which you do not know the answer”… chasing a compliance chain can be a > open-ended problem as people would become more daring with the feature and > projects would rely on more and more pre-canned modules. > > thank you for your patient explanations. Many thanks from me as well. I, too, appreciate that very much! -Thorsten > >> >> - Doug >> >>> >>> -Thorsten >>> >>> >>>> >>>> That’s a fairly significant expansion, and for each of the protocol >>>> extensions in (3), we need to evaluate whether X conforms to the extended >>>> protocol Q (and any additional constraints placed on that protocol >>>> extension). >>>> >>>> - Doug >>>> >>>> >>>>> >>>>> On Jun 5, 2016, at 9:49 AM, Thorsten Seitz via swift-evolution >>>>> <[email protected]> wrote: >>>>> >>>>>> >>>>>>> Am 04.06.2016 um 23:18 schrieb Austin Zheng via swift-evolution >>>>>>> <[email protected]>: >>>>>>> >>>>>>> Hello Dan, >>>>>>> >>>>>>> You'll be pleased to learn that conforming generic types conditionally >>>>>>> to protocols is on the roadmap (and is one of the highest priority >>>>>>> items for the versions of Swift following 3.0): >>>>>>> https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#conditional-conformances- >>>>>>> >>>>>>> However, it's unlikely that protocols will gain conditional >>>>>>> conformance: >>>>>>> https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#conditional-conformances-via-protocol-extensions >>>>>> >>>>>> "However, similar to private conformances, it puts a major burden on the >>>>>> dynamic-casting runtime to chase down arbitrarily long and potentially >>>>>> cyclic chains of conformances, which makes efficient implementation >>>>>> nearly impossible.“ >>>>>> >>>>>> I’ve been wondering what the problem with the implementation is. I mean >>>>>> instead of using an extension the same conformance could have been >>>>>> declared beforehand, i.e. instead of >>>>>> >>>>>> protocol P { func foo() } >>>>>> protocol Q { func bar() } >>>>>> extension Q : P { func foo() { bar() } } >>>>>> >>>>>> we could have written the allowed >>>>>> >>>>>> protocol P { func foo() } >>>>>> protocol Q : P { func foo() { bar() } } >>>>>> >>>>>> with the exact same effect. >>>>>> >>>>>> The only difference would be that the extension might have been in >>>>>> another module than Q. >>>>>> Is having to cross module boundaries causing the cited problems? Would >>>>>> the same problems exist if in the second example Q would be defined in >>>>>> another module? >>>>>> >>>>>> -Thorsten >>>>>> >>>>>> >>>>>>> >>>>>>> That document originates from a mailing list post made some time ago, >>>>>>> and is a decent overview as to what sorts of type system features the >>>>>>> Swift core developers are interested in building. >>>>>>> >>>>>>> Best, >>>>>>> Austin >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
