[swift-evolution] [Draft] Mixins

Wallacy wallacyf at gmail.com
Thu Apr 21 10:27:10 CDT 2016


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 <
swift-evolution at swift.org> 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 <
> swift-evolution at swift.org> 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: <
>> CAEbsasTVGD6NEZdnFhTMWVwuNc7EBDqatJAJhZFn4vOxdVPBiA at 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" <
>> swift-evolution-m3FHrko0VLzYtjvyW6yDsg at public.gmane.org> 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
>> >niall-AFFH1GffN5hPR4JQBCEnsQ at public.gmane.org
>> >
>> >
>> >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
>> >swift-evolution-m3FHrko0VLzYtjvyW6yDsg at public.gmane.org
>> >https://lists.swift.org/mailman/listinfo/swift-evolution
>> >
>>
>>
>>
>> ------------- End Message -------------
>>
>>
>>
>> From James F
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>
> _______________________________________________
> 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/20160421/a0cad009/attachment.html>


More information about the swift-evolution mailing list