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