FWIW: Im working on a proposal to cover this points, using protocols a few days. One or two days i will post...
Em qui, 21 de abr de 2016 09:27, Tal Atlas via swift-evolution < [email protected]> escreveu: > I agree that the solution to any of these problems would be better done > with improvements to protocol extensions. Having multiple tools to get the > same trick done doesn’t seem worth it in this case. > > -Tal > > On Thu, Apr 21, 2016 at 7:00 AM, James Froggatt via swift-evolution < > [email protected]> wrote: > >> I sometimes find myself wanting to use private protocols + extensions to >> try to add public functions to a set of types. Something like this: >> >> private protocol ArrayBackedType { >> var data: [String] {get set} >> } >> public extension ArrayBackedType: UITableViewDataSource { >> /*standard table view methods here*/ >> } >> >> This would currently require two changes to the language: public >> extensions to private protocols, and support for ObjC-compatible functions >> in extensions (which should be possible for private/internal protocols). >> >> Additionally, extensions could get the ability to add storage to the >> (non-imported) type they extend, so: >> >> internal protocol ArrayBackedType {} >> public extension ArrayBackedType: UITableViewDataSource { >> private var data: [String] = [] >> dynamic func tableView(…) >> } >> >> The separate protocol & extension declarations could then get some >> syntactic sugar: >> >> /*can't be public, since it can add properties, internal availability >> matches that of the protocol in the previous example*/ >> internal protocol extension ArrayBackedType { … } >> >> or even more concisely: >> internal trait ArrayBackedType { … } >> >> Could traits be constructed from protocol extensions in this way, or >> otherwise end up competing with them if just some of these features were to >> be added? My concern is that adding traits as a separate language feature >> could put them in direct competition with protocol extensions. >> >> ------------ Begin Message ------------ >> Group: gmane.comp.lang.swift.evolution >> MsgID: < >> caebsastvgd6nezdnfhtmwvwunc7ebdqatjajhzfn4voxdvp...@mail.gmail.com> >> >> Another traits implemenation >> >> http://php.net/manual/en/language.oop5.traits.php >> On Apr 21, 2016 5:53 PM, "Niall Young via swift-evolution" < >> [email protected]> wrote: >> >> >At Tue Mar 1 19:00:21 CST 2016, Brian Pratt brian at pratt.io wrote: >> > >> >I feel like the solution to the Arrow/Enemy problem that best fits with >> >>Swift's current available tools is neither a protocol (which, as you >> >>mentioned, doesn't get rid of the initialization/configuration of the >> >>member data) or inheritance (which, as you mentioned, can only have one >> >>base type) -- it's to extract a third type that handles >> >> >> > >> >What you're describing sounds _exactly_ like Traits :-) >> > >> >http://scg.unibe.ch/research/traits >> > >> >Traits could be a peer of extensions, filling a niche that isn't quite >> the >> >same niche as a default implementation, but it could be consistently and >> >safely consumed like an extension, with its own rules of consumption >> >(flattening) - to implement any need or explicit protocol requirement >> that >> >a Class, Value Type or Protocol has at compile-time. >> > >> >Think of a Trait as providing a consumable set of functions. Now imagine >> >that we're combining the collective declarations of 1..N Traits all >> >together, consumed by a Class or Value Type (or Protocol!) in a >> predicable >> >and safe way (flattening: see the first Traits white paper). >> > >> >i.e. we get the same result regardless of the order of consumption, how >> >many times any given Trait(s) were consumed, Traits dependent on other >> >Traits etc. Predictable results, given the same input we always get the >> >same output. This is flattening, but read the white papers for more >> detail. >> > >> >The process of flattening itself could be a peer of the existing rules >> >around static dispatch vs. dynamic dispatch around >> >default-implementations/extensions vs. class overrides. >> > >> >A Trait declaration could look something ~like: >> > >> >trait TraitX (ProtocolAdherenceY): DependentTrait1, >> >DependentTrait2 { >> > >> >private var foo >> >private let bah { .. } >> > >> >func fooify { .. } >> >mutating func bahify { .. } >> >private func hah { .. } >> > >> >} >> > >> >with a Trait being a closure, where _only private_ data Properties can be >> >declared, providing 1..N function implementations. It could conform >> >_towards_ a Protocol (partial to full conformance), and also be dependent >> >upon other names Traits, which would be consumed in parallel as a >> >first-class citizen with the Trait that depends on it. >> > >> >Traits could be consumed by a class or value type, to provide function >> >implementations which could be satisfying a Protocol implementation >> >requirement, along with its own private functions and private data for >> its >> >(private to Trait) local state etc. The consumption syntax I'm still >> >unsure of, but a clear declarative "flattens Trait1, Trait2, .. , TraitN" >> >or similar would do. >> > >> >The consuming Class or Value Type would remain fully responsible for its >> >own Protocol conformance, and if any of the consumed Trait public >> >implementations conflict or overlap with each other, then the conflicts >> >must be resolved explicitly by the Class or Value Type itself, where it >> is >> >consumed. >> > >> >The resulting "flattened" set of Traits would be input towards the Type's >> >own compiler requirements, with the author being required to explicitly >> >resolve any and all conflicts at compile-time. Cconsumption at run-time >> >could be a later feature as Swift's core stabilises and specific run-time >> >metaprogramming facilities are exposed. >> > >> >Explicit conflict resolution, via a flattened 2D matrix of Trait:func >> >identifying conflicts that need to be resolved by the consumer, also >> gives >> >reliable results with no cognitive overhead as Brian's identified in >> >resolving Mixin consumption. Plus there is no diamond-problem, as there >> is >> >no inheritance. With Traits, it _must_ be resolved explicitly in code, >> >with suitable compiler errors for malformed Types that have consumed 1..N >> >Trait(s). >> > >> >Stateful Traits suggest that as long as the data is private _to the >> Trait_ >> >then we can safely ignore some of the complexity of state in Traits - it >> >just isn't exposed as the Trait declaration itself is a closure. >> >Dependency on state in the consumer could proxy to >> >class/instance/value-type data via Protocol. >> > >> >Swift and Protocols seem like a perfect match for "capital-T" Traits. >> Any >> >thoughts on if this is suitable for a 3.0 or 4.0 Proposal? >> > >> >I've recently built similar mechanisms exploring these concepts with >> basic >> >metaprogramming and a common root class in a dynamic language, but as a >> >core language feature of Swift I think it could very much complement the >> >existing protocols and extension concepts, with 1..N re-usable >> >implementations, and it also could help to resolves the uncertainty/rules >> >around static vs. dynamic dispatch: static could remain the domain of >> >extensions / default implementations; with dynamic dispatch available to >> >Classes and Traits? >> > >> >More Reading: >> > >> >http://scg.unibe.ch/research/traits >> > >> >Cheers, >> > >> >-- >> >Niall Young >> >[email protected] >> > >> > >> >At Tue Mar 1 19:00:21 CST 2016, Brian Pratt brian at pratt.io wrote: >> > >> >I think this sort of composition is preferable to inheritance in a lot of >> >>ways, and Swift has some built-in tools that can augment it: a robust >> >>protocol and extension system, a type constraint system that allows for >> >>lots of flexibility at compile-time, etc. >> >> >> >>Mixins (and in general, the sharing of code primarily via inheritance) >> >>tend >> >>to create large objects with lots of responsibilities, and that tends to >> >>bloat APIs as you need to either pick extremely specific names to avoid >> >>collisions, or worse, keep the cognitive overhead of "shoot, what is >> this >> >>method aliased to again?" in your head all the time. If something *is* >> >>both >> >>an A and a B, it needs to act like (and speak the same language of) an A >> >>or >> >>a B *all* of the time. >> >> >> >>Beyond this, I think it's going to be extremely complex managing >> >>compile-time type constraints with renames in place. Let's say I have a >> >>class C that inherits from bases A and B, which implement protocol P >> and Q >> >>respectively, and there's a naming collision. Functions that expect Ps >> or >> >>Qs will have to know about the renaming of conflicts from the >> combination >> >>of A+B? Unless I'm missing something, it feels like this complexity >> would >> >>continue to spread out to all sorts of collaborators, when the current >> >>system isolates it much more effectively. >> >> >> > >> >I think protocols and protocol extensions (mixed with lots of >> composition) >> >>is a better scenario than abstract classes or multiple inheritance, and >> >>therefore, I'm still a -1 on mixins in Swift (strictly on principle; >> this >> >>proposal actually argues the case very well). >> >> >> >>- Brian >> >> >> > >> >And agreed Thorsten!: >> > >> >Unfortunately the current discussions about Mixins, abstract classes, POP >> >>>vs. OOP suffer from having forgotten achievements of the past which >> >>>results >> >>>in creating differences where none should be. >> >>> >> >> >> >It is unfortunate and IMO just for historical reasons that there is a >> >>>dichotomy between protocols and classes at all instead of having just >> >>>classes with multiple inheritance done right (and abstract methods). >> >>> >> >> >> >- We should extend protocols to support real multiple inheritance with >> >>>renaming >> >>> >> >> >> >-Thorsten >> >>> >> >>_______________________________________________ >> >swift-evolution mailing list >> >[email protected] >> >https://lists.swift.org/mailman/listinfo/swift-evolution >> > >> >> >> >> ------------- End Message ------------- >> >> >> >> From James F >> _______________________________________________ >> swift-evolution mailing list >> [email protected] >> https://lists.swift.org/mailman/listinfo/swift-evolution >> > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
