[swift-evolution] [Draft] Mixins

Howard Lovatt howard.lovatt at gmail.com
Sat Feb 27 20:49:35 CST 2016


Thanks for clarifying `protocol<A, B>`. In that case  `protocol<A, B>` is
not necessarily an error for traits, but the ambiguity needs resolving.

On Sunday, 28 February 2016, Joe Groff via swift-evolution <
swift-evolution at swift.org> wrote:

> Howard Lovatt via swift-evolution
> <swift-evolution at swift.org <javascript:;>> wrote:
> > I like the proposal but would suggest you rename it Trait and not Mixin,
> > since you proposal has Trait and not Mixin behaviour. The difference is
> > that the order of inheritance is not important with Traits but is with
> > Mixins, EG:
> >
> >     protocol A { let msg = "A" }
> >     protocol B { let msg = "B" }
> >     struct MixinAB: A, B {}
> >     MixinAB().msg // B
> >
> >   Whereas
> >
> >     struct MixinBA: B, A {}
> >     MixinBA().msg // A
> >
> > With traits the order is not important, and has to be resolved by the
> > programmer when a conflict arises:
> >
> >     struct ErrorAB: A, B {} // An error because there are two `msg`s.
> >
> > You have to do:
> >
> >     struct TraitAB: A, B { // Could be B, A - makes no difference
> >         let msg = A.msg // Select A's definition, could be `= B.msg`,
> could
> > be `= 3` (i.e. any valid Swift)
> >     }
> >
> > As an aside I don't get what you mean by your example:
> >
> > protocol<A, B>  // error
>
> This is the spelling for the protocol composition of A and B.
>
> >
> > Protocols cannot be generic!
> >
> > On Sunday, 28 February 2016, Anton Zhilin via swift-evolution <
> > swift-evolution at swift.org <javascript:;>> wrote:
> >
> >> 0. Please read the whole proposal and this whole message before
> replying.
> >>
> >> 1.
> >>> In short words, protocol will became a sort of class and no longer a
> >> true kind of contract to conform to.
> >>
> >> There is an option to introduce "mixin" keyword:
> >> mixin M {
> >> var storage: Int = 0
> >> }
> >> It won't cause confusion with today's protocols.
> >> For difference from classes, see under 3.
> >>
> >> 2.
> >>> What about compatibility with Objective C ?
> >>
> >> Protocols cannot inherit from classes, including NSObject.
> >> [Warning: IMO ahead]
> >> But I personally think that we should move from abstract classes in
> Obj-C,
> >> where possible. Actually, all classes in Obj-C can be instantiated, so I
> >> consider this a bad abstraction.
> >>
> >> 3.
> >>> (see David's message)
> >> Firstly, what you've shown is not a diamond problem. No dequate
> >> programming language would allow you to do what you've shown. Secondly,
> >> please read the whole proposal, as I specifically addressed the issue
> there.
> >>
> >> Now, to difference from classes.
> >> The largest difference between classes and mixins comes in inheritance.
> We
> >> can allow multiple inheritance, because we can solve diamond problem
> with
> >> mixins.
> >> Let's take the example from my proposal:
> >>
> >> protocol A { var x: Int = 1 }
> >> protocol B: A { }
> >> protocol C: A { }
> >> struct D : B, C { }
> >>
> >> What really happens here is the following:
> >>
> >> protocol ASelf { var x: Int = 1 }
> >> protocol BSelf { }
> >> protocol CSelf { }
> >> struct D : ASelf, BSelf, CSelf { }
> >>
> >> We can do this, because mixins are statically dispatched. The compiler
> >> will enumerate all included mixins and mix in only one version of each.
> >> I said statically dispatched, but in Swift, compiler can automatically
> >> create wrappers with necessary closures inside if we need dynamic
> dispatch
> >> for protocols, so that is not a real concern.
> >> Diamond problem is solved the same way in Python and Ruby, so I'm not
> >> inventing something new here.
> >> Mixins tend to "mix in behaviours". Let's take an example usage of
> diamond
> >> pattern:
> >>
> >> protocol SignalSender {
> >> private var slots: [String: [() -> ()]] = []
> >> func connect(signal: String, to slot: () -> ()) { ... }
> >> func fire(signal: String) { ... }
> >> }
> >> protocol A : SignalSender {
> >> // Use signal functionality
> >> }
> >> protocol B : SignalSender {
> >> // Use signal functionality
> >> }
> >> struct C : A, B { }
> >>
> >> A and B both use a single SignalSender, incorporated within final
> object.
> >> If SignalSender supports its invariants through incapsulation, nothing
> will
> >> ever break them. If it doesn't, then, well, this mixin is not perfectly
> >> suited for multiple inheritance.
> >>
> >> If you have reached this far, thank you!
> >> _______________________________________________
> >> swift-evolution mailing list
> >> swift-evolution at swift.org <javascript:;> <javascript:;>
> >> https://lists.swift.org/mailman/listinfo/swift-evolution
> >>
> >
> >
>
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <javascript:;>
> https://lists.swift.org/mailman/listinfo/swift-evolution
>


-- 
-- Howard.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160228/14e576b5/attachment.html>


More information about the swift-evolution mailing list