<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><br><br><div>Regards</div>(From<span class="Apple-style-span" style="-webkit-tap-highlight-color: rgba(26, 26, 26, 0.296875); -webkit-composition-fill-color: rgba(175, 192, 227, 0.230469); -webkit-composition-frame-color: rgba(77, 128, 180, 0.230469); ">&nbsp;mobile)</span></div><div><br>On Jun 25, 2016, at 6:34 PM, Thorsten Seitz via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8">Sorry for the late reply — I had hoped to be able to think more deeply about various points,&nbsp;<div class="">but I’m going to delay that instead of delaying the reply even more :-)<div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div><blockquote type="cite" class=""><div class="">Am 17.06.2016 um 19:04 schrieb Dave Abrahams &lt;<a href="mailto:dabrahams@apple.com" class="">dabrahams@apple.com</a>&gt;:</div><br class="Apple-interchange-newline"><div class=""><div class=""><br class="">on Thu Jun 16 2016, Thorsten Seitz &lt;<a href="http://tseitz42-at-icloud.com" class="">tseitz42-AT-icloud.com</a>&gt; wrote:<br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">Am 13.06.2016 um 04:04 schrieb Dave Abrahams &lt;<a href="mailto:dabrahams@apple.com" class="">dabrahams@apple.com</a>&gt;:<br class=""><br class=""><br class="">on Fri Jun 10 2016, Thorsten Seitz &lt;<a href="http://tseitz42-at-icloud.com" class="">tseitz42-AT-icloud.com</a>&gt; wrote:<br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">Am 09.06.2016 um 19:50 schrieb Thorsten Seitz via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt;:<br class=""><br class=""><br class=""><blockquote type="cite" class="">Am 09.06.2016 um 18:49 schrieb Dave Abrahams via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt;:<br class=""></blockquote></blockquote><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><br class="">on Wed Jun 08 2016, Jordan Rose &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">On Jun 8, 2016, at 13:16, Dave Abrahams via swift-evolution<br class="">&lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class=""><br class="">on Wed Jun 08 2016, Thorsten Seitz<br class=""></blockquote><br class=""><blockquote type="cite" class="">&lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">&lt;<a href="mailto:swift-evolution@swift.org" class="">mailto:swift-evolution@swift.org</a>&gt;&gt;<br class="">wrote:<br class=""><br class=""><blockquote type="cite" class="">Ah, thanks, I forgot! &nbsp;I still consider this a bug, though (will have<br class="">to read up again what the reasons are for that behavior).<br class=""></blockquote><br class="">Yes, but in the case of the issue we're discussing, the choices are:<br class=""><br class="">1. Omit from the existential's API any protocol requirements that depend<br class="">on Self or associated types, in which case it *can't* conform to<br class="">itself because it doesn't fulfill the requirements.<br class=""><br class="">2. Erase type relationships and trap at runtime when they don't line up.<br class=""><br class="">Matthew has been arguing against #2, but you can't “fix the bug” without<br class="">it.<br class=""></blockquote><br class="">#1 has been my preference for a while as well, at least as a starting<br class="">point.<br class=""></blockquote><br class="">I should point out that with the resyntaxing of existentials to<br class="">Any&lt;Protocols...&gt;, the idea that Collection's existential doesn't<br class="">conform to Collection becomes far less absurd than it was, so maybe this<br class="">is not so bad.<br class=""></blockquote><br class="">I think the problem is more that Any&lt;Collection&gt; does not conform to<br class="">a specific value for a type parameter T: Collection<br class=""><br class="">What I mean by this is that `Collection` denotes a type family, a<br class="">generic parameter `T: Collection` denotes a specific (though<br class="">unknown) member of that type family and `Any&lt;Collection&gt;` denotes<br class="">the type family again, so there is really no point in writing<br class="">Any&lt;Collection&gt; IMO.<br class="">The type family cannot conform to T because T is just one fixed member of it.<br class="">It conforms to itself, though, as I can write<br class="">let c1: Any&lt;Collection&gt; = …<br class="">let c2: Any&lt;Collection&gt; = c1<br class=""><br class="">That’s why I think that we could just drop Any&lt;Collection&gt; and simply write Collection.<br class=""></blockquote><br class="">Let me expand that a bit:<br class=""><br class="">Actually all this talk about existentials vs. generics or protocols<br class="">vs. classes has had me confused somewhat and I think there are still<br class="">some misconceptions present on this list sometimes, so I’ll try to<br class="">clear them up:<br class=""></blockquote><br class="">There are several objectively incorrect statements here, and several<br class="">others with which I disagree. &nbsp;I was hoping someone else would write<br class="">this for me, but since the post has such a tone of authority I feel I<br class="">must respond.<br class=""></blockquote><br class="">You are right, the tone of my post was not appropriate, for which I<br class="">want to apologize sincerely.<br class=""></blockquote><br class="">My fundamental disagreement is with the content, not the tone.<br class=""><br class=""><blockquote type="cite" class="">I still believe my statements to be valid, though, and will respond to<br class="">your arguments inline. Please don't get me wrong, I'm not trying to<br class="">have an argument for the argument's sake. All I want is to contribute<br class="">maybe a tiny bit to make Swift even better than it already is, by<br class="">sharing ideas and thoughts not only from me but from the designs of<br class="">other perhaps more obscure programming languages which I happen to<br class="">have stumbled upon in the past (often with much delight).<br class=""></blockquote><br class="">And I want you to know, even though I disagree with what you've written,<br class="">that I very much appreciate the contribution you're making.<br class=""></div></div></blockquote><div><br class=""></div>Thanks! I’m very glad about that!</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">(1) misconception: protocols with associated types are somehow very<br class="">different from generics<br class=""><br class="">I don’t think they are and I will explain why. The only difference is<br class="">the way the type parameters are bound: generics use explicit parameter<br class="">lists whereas protocols use inheritance. That has some advantages<br class="">(think long parameter lists of generics) and some disadvantages.<br class="">These ways are dual in a notation sense: generic types have to have<br class="">all parameters bound whereas protocols cannot bind any of them.<br class="">The „existential“ notation `Any&lt;&gt;` being discussed on this list is<br class="">nothing more than adding the ability to protocols to bind the<br class="">parameters to be used just like Java’s wildcards are adding the<br class="">opposite feature to generics, namely not having to bind all<br class="">parameters.<br class=""></blockquote><br class="">Protocols and generics fulfill completely different roles in Swift, and<br class="">so, **especially in a language design context like the one we're in<br class="">here**, must be thought of differently. &nbsp;The former are an abstraction<br class="">mechanism for APIs, and the latter a mechanism for generalizing<br class="">implementations. &nbsp;<br class=""></blockquote><br class="">That's not what I was talking about. Of course, protocols are a<br class="">mechanism for deriving types from each other whereas generics are a<br class="">way to parameterize types. My point was that Swift's other way to<br class="">parameterize types, namely by associated types, is very similar to<br class="">generics with wildcards when looking a the existentials of such<br class="">protocols. In addition I was talking about generics in general, not<br class="">just about generics in Swift which restricts them to implementations<br class="">and does not support wildcards.<br class=""></blockquote><br class="">I'm aware of these other systems. &nbsp;One of the problems with the way<br class="">you're writing about this is that we're speaking in the context of Swift<br class="">and you're assuming a completely open design space, as though Swift's<br class="">choice to sharply distinguish classes from protocols was not a conscious<br class="">one... but it was. &nbsp;</div></div></blockquote><div><br class=""></div><div>I never had assumed that this had been decided lightly ;-)</div><div>And I have been favorably impressed by the rationales put forth so far by the Swift&nbsp;</div><div>team, so it would definitely be interesting to learn a bit more about the rationale</div><div>being put into that decision and the advantages and disadvantages discussed back then.</div><div>Is there something written down somewhere?&nbsp;</div><div><br class=""></div></div></div></div></div></blockquote><div><br></div><div>I think some applicable rational exist in type-system papers that came out of studying scala's.&nbsp;</div><br><blockquote type="cite"><div><div class=""><div class=""><div><blockquote type="cite" class=""><div class=""><div class="">Yes, Swift could have been designed differently, so<br class="">that a single language construct, a kind of generic class, was stretched<br class="">so it could express almost everything. &nbsp;Personally, I don't believe that<br class="">results in a better language.<br class=""></div></div></blockquote><div><br class=""></div><div>I still believe it would have advantages but I’ll concede that this discussion&nbsp;</div><div>will probably not help advancing Swift as this decision has been made.</div><div>Still, it might be of interest to keep in mind for further design considerations.</div></div></div></div></div></blockquote><div><br></div><div>Somehow the world of languages is small, and tracing inspiriation across is playing permutations on a limited set.&nbsp;</div><br><blockquote type="cite"><div><div class=""><div class=""><div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class="">Other languages like Java offer generics for interfaces as well and<br class="">support wildcards (adding generic types parameters to protocols in<br class="">Swift is currently discussed on the mailing list as well). &nbsp;FWIW my<br class="">arguments were not about whether we should have wildcards in Swift or<br class="">not, but simply to relate one parametrization feature (associated<br class="">types) to a more well known parametrization feature (generics with<br class="">wildcards) in order to understand them better.<br class=""><br class=""><blockquote type="cite" class="">The only place you could argue that they intersect is<br class="">in generic non-final classes, because a class fills the dual role of<br class="">abstraction and implementation mechanism (and some might say that's a<br class="">weakness). &nbsp;But even accounting for generic classes, protocols with<br class="">associated types are very different from generics. &nbsp;Two utterly<br class="">different types (an enum and a struct, for example) can conform to any<br class="">given protocol P, but generic types always share a common basis<br class="">implementation. &nbsp;<br class=""></blockquote><br class="">The latter is not the case for generic interfaces in Java, for<br class="">example, so it is just an artificial restriction present in Swift.<br class=""></blockquote><br class="">It's not an artificial restriction, it's a design choice. &nbsp;Sure, if by<br class=""></div></div></blockquote><div><br class=""></div><div><div>I meant artifical in the sense that a different design choice would have been possible.</div><div class=""><br class=""></div></div><br class=""><blockquote type="cite" class=""><div class=""><div class="">“generic type” you just mean anything that encodes a static type<br class="">relationship, lots of things fall into that bucket.<br class=""></div></div></blockquote><div><br class=""></div></div><div>Well, I think Java’s generics are not that advanced, so the bucket does not&nbsp;</div><div>have to be very big :-)</div></div></div></div></blockquote><div><br></div><div>I am curious to see what language you have in mind when you are making a comparison?</div><br><blockquote type="cite"><div><div class=""><div class=""><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">There is no way to produce distinct instances of a generic type with<br class="">all its type parameters bound,<br class=""></blockquote><br class="">That is true in Swift (except for generic classes) due to the<br class="">restriction just mentioned.<br class=""><br class=""><blockquote type="cite" class="">but for any protocol P I can make infinitely many instances of P with<br class="">P.AssociatedType == Int.<br class=""></blockquote><br class="">This likewise applies to generic interfaces and for generic types in<br class="">general if taking inheritance into account - just like you do here for<br class="">protocols.<br class=""><br class=""><blockquote type="cite" class="">Back to the my original point: while protocols and generic types have<br class="">some similarities, the idea that they are fundamentally the same thing<br class="">(I know you didn't say *exactly* that, but I think it will be read that<br class="">way) would be wrong and a very unproductive way to approach language<br class="">evolution.<br class=""></blockquote><br class="">I said that protocols *with associated types* are much like generics<br class="">*with wildcards* and tried to show why.<br class=""></blockquote><br class="">If all you're trying to do is say that there's an analogy there, then we<br class="">have no argument.<br class=""></div></div></blockquote><div><br class=""></div>Ok.</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">Essentially `Any&lt;Collection&gt;` in Swift is just the same as<br class="">`Collection&lt;?&gt;` in Java (assuming for comparability’s sake that<br class="">Swift’s Collection had no additional associated types; otherwise I<br class="">would just have to introduce a Collection&lt;Element, Index&gt; in Java).<br class=""></blockquote><br class="">I don't see how you can use an example that requires *assuming away*<br class="">assoociated types to justify an argument that protocols *with associated<br class="">types* are the same as generics.<br class=""></blockquote><br class="">Note, that I said *additional* associated types, i.e. in addition to<br class="">.Element, even giving an example how the Java interface had to be<br class="">extended by a type parameter `Index` if this assumption was not<br class="">applied (still simplifying because Generator would have been more<br class="">correct which would have to be added as type parameter in addition to<br class="">`Index`).<br class=""><br class="">So, in essence the comparison is between the following (I'm using Foo<br class="">now instead of Collection to avoid the differences mentioned. Note<br class="">that this has no impact on the argument at all):<br class=""><br class="">protocol Foo {<br class=""> &nbsp;&nbsp;&nbsp;associatedtype T<br class=""> &nbsp;&nbsp;&nbsp;...<br class="">}<br class=""><br class="">interface Foo&lt;T&gt; {<br class=""> &nbsp;&nbsp;&nbsp;...<br class="">}<br class=""></blockquote><br class="">Yes, those correspond.<br class=""><br class=""><blockquote type="cite" class="">My argument is that existentials of protocols with associated types<br class="">are just like generic types with wildcards, i.e. `Any&lt;Foo&gt;` in Swift<br class="">is just the same as `Foo&lt;?&gt;` in Java.<br class="">Likewise `Any&lt;Foo where .T: Number&gt;` is just the same as `Foo&lt;?<br class="">extends Number&gt;` in Java. For me that was an insight I wanted to<br class="">share.<br class=""></blockquote><br class="">It's a good one.<br class=""></div></div></blockquote><div><br class=""></div>Thanks!</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">And just like Collection&lt;?&gt; does not conform to a type parameter `T<br class="">extends Collection&lt;?&gt;` because Collection&lt;?&gt; is the type `forall<br class="">E. Collection&lt;E&gt;` whereas `T extends Collection&lt;?&gt;` is the type<br class="">`T. Collection&lt;T&gt;` for a given T.<br class=""><br class="">In essence protocols with associated types are like generics with<br class="">wildcards.<br class=""></blockquote><br class="">It is true that generics with wildcards in Java *are* (not just “like”)<br class="">existential types but I don't agree with the statement above. &nbsp;Because<br class="">Java tries to create an “everything is a class” world, generic classes<br class="">with bound type parameters end up playing the role of existential type.<br class="">But protocols in Swift are not, fundamentally, just existential types,<br class="">and the resyntaxing of ProtocolName to Any&lt;ProtocolName&gt; for use in type<br class="">context is a huge leap forward in making that distinction clear... when<br class="">that's done (unless we leave Array&lt;ProtocolName&gt; around as a synonym for<br class="">Array&lt;Any&lt;ProtocolName&gt;&gt;—I really hope we won't!) &nbsp;protocols indeed<br class="">*won't* be types at all, existential or otherwise.<br class=""></blockquote><br class="">I fully agree that protocols are not types, their existentials<br class="">are. But I haven't seen yet what we really *gain* from making that<br class="">distinction explicit (except an ugly type syntax :-).<br class=""></blockquote><br class="">For me, it helps distinguish static from dynamic polymorphism.<br class=""></div></div></blockquote><div><br class=""></div><div>Hmm, I’ll have to think more about that.</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class="">And like I already wrote in this or another thread we would have to<br class="">apply the same logic to non-final classes, which are existentials,<br class="">too.<br class=""><blockquote type="cite" class=""><br class=""><blockquote type="cite" class="">Coming back to the questions whether (a) allowing existentials to be<br class="">used as types is useful<br class=""></blockquote><br class="">That's the only use existentials have. &nbsp;They *are* types. &nbsp;Of course<br class="">they're useful, and I don't think anyone was arguing otherwise.<br class=""></blockquote><br class="">I'm pretty sure that there was a discussion about whether being able<br class="">to write something like Any&lt;Collection&gt; is useful. My wording was<br class="">certainly imprecise, though, and didn't make sense as written. I<br class="">should have said something like "whether adding the ability to use<br class="">existential types of protocols with unbound associated types is<br class="">useful".<br class=""><br class=""><blockquote type="cite" class=""><br class=""><blockquote type="cite" class="">and (b) whether sacrificing type safety would somehow be necessary for<br class="">that, I think we can safely answer (a) yes, it *is* useful to be able<br class="">to use existentials like Any&lt;Collection&gt; as types, because wildcards<br class="">are quite often needed and very useful in Java (they haven’t been<br class="">added without a reason) (b) no, sacrificing type safety does not make<br class="">sense, as the experience with Java’s wildcards shows that this is not<br class="">needed.<br class=""></blockquote><br class="">I would call this “interesting information,” but hardly conclusive.<br class="">Java's generics are almost exactly the same thing as Objective-C<br class="">lightweight generics, which are less capable and less expressive in<br class="">many ways than Swift's generics. &nbsp;<br class=""></blockquote><br class="">I agree that Java does not have something like `Self` or associated<br class="">types (which are really useful for not having to bind all type<br class="">parameters explicitly, especially when binding type parameters to<br class="">other generics which makes for long type parameter lists in Java where<br class="">I have to repeat everything over and over again), but do you mean<br class="">something else here?<br class="">Especially in the context of sacrificing type safety?<br class=""></blockquote><br class="">I do, but it will take some research for me to recover my memory of<br class="">where the holes are. &nbsp;It has been years since I thought about Java<br class="">generics. &nbsp;It's also possible that I'm wrong ;-)</div></div></blockquote><div><br class=""></div>If you happen to remember, I’d be interested in hearing about the problems you meant.</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">Especially if something like path dependent types is used like<br class="">proposed and some notation to open an existential’s type is added,<br class="">which is both something that Java does not have.<br class=""><br class="">(2) misconception: POP is different from OOP<br class=""><br class="">It is not. Protocols are just interfaces using subtyping like OOP has<br class="">always done. They just use associated types instead of explicit type<br class="">parameters for generics (see above).<br class=""></blockquote><br class="">They are not the same thing at all (see above ;-&gt;). &nbsp;To add to the list<br class="">above, protocols can express fundamental relationships—like Self<br class="">requirements—that OOP simply can't handle.<br class=""></blockquote><br class="">Eiffel has something like Self, it is called anchoring and allows<br class="">binding the type of a variable to that of another one or self (which<br class="">is called `Current` in Eiffel). And Eiffel does model everything with<br class="">classes which may be abstract and allow for real multiple inheritance<br class="">with abilities to resolve all conflicts including those concerning<br class="">state (which is what other languages introduce interfaces for to avoid<br class="">conflicts concerning state while still failing to solve *semantic*<br class="">conflicts with the same diamond pattern).<br class="">No protocols or interfaces needed. Why do you say this is not OOP? The<br class="">book which describes Eiffel is called "Object-Oriented Software<br class="">Construction" (and is now about 20 years old).<br class=""></blockquote><br class="">It's not *incompatible* with OOP, but it is not part of the essence of<br class="">OOP either. &nbsp;If you survey object-oriented languages, what you find in<br class="">common is inheritance-based dynamic polymorphism and reference<br class="">semantics. &nbsp;Those are the defining characteristics of OOP, and taking an<br class="">object-oriented approach to a given problem means reaching for those<br class="">features.<br class=""></div></div></blockquote><div><br class=""></div>Agreed, it is not part of most OOP *implementations* while being compatible with OOP.</div><div>There have been lots of papers and research languages about typing problems like&nbsp;</div><div>binary methods, null pointers etc., though, so taking the mainstream OO languages</div><div>as the yardstick for OOP is jumping a little bit too short IMO.&nbsp;</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class=""><blockquote type="cite" class="">There's a reason Java can't<br class="">express Comparable without losing static type-safety. &nbsp;<br class=""></blockquote><br class="">You are certainly right that Java is not the best language out there<br class="">especially when talking about type systems (I often enough rant about<br class="">it :-) but I'm not sure what you mean here. Java's Comparable&lt;T&gt; seems<br class="">quite typesafe to me. Or do you mean that one could write `class A<br class="">implements Comparable&lt;B&gt;` by mistake? That's certainly a weak point<br class="">but doesn't compromise type safety, does it?<br class=""></blockquote><br class="">Java has cleverly avoided compromising type safety here by failing to<br class="">express the constraint that comparable conformance means a type can be<br class="">compared to itself ;-)<br class=""></div></div></blockquote><div><br class=""></div>Indeed :-)</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class="">Ceylon has an elegant solution for that without using Self types:<br class=""><br class="">interface Comparable&lt;in Other&gt; of Other given Other satisfies Comparable&lt;Other&gt; {...}<br class=""><br class="">Note the variance annotation (which Swift currently has not) and the<br class="">`of` which ensures that the only subtype of Comparable&lt;T&gt; is T. This<br class="">is a nice feature that I haven't seen often in programming languages<br class="">(only Cecil comes to mind IIRC) and which is used for enumerations as<br class="">well in Ceylon. In Swift I cannot do this but can use Self which<br class="">solves this problem differently, albeit with some drawbacks compared<br class="">to Ceylon's solution (having to redefine the compare method in all<br class="">subtypes, <br class=""></blockquote><br class="">That sounds interesting but is a bit vague. &nbsp;A concise example of how<br class="">this plays out in Swift and in Ceylon would be instructive here.<br class=""></div></div></blockquote><div><br class=""></div>Sorry, the difficulty with Self I was thinking of only occurs when Self is in a covariant position</div><div>which is not the case in Comparable, of course. Let’s take a modified example instead with Self&nbsp;</div><div>in a covariant position:</div><div><br class=""></div><div>Swift:</div><div><br class=""></div><div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">protocol</span><span style="font-variant-ligatures: no-common-ligatures" class=""> Minimizable {</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> min(from other: </span><span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">Self</span><span style="font-variant-ligatures: no-common-ligatures" class="">) -&gt; </span><span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">Self</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150); min-height: 15px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(181, 137, 1);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">final</span><span style="font-variant-ligatures: no-common-ligatures; color: #839496" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">class</span><span style="font-variant-ligatures: no-common-ligatures; color: #839496" class=""> A : </span><span style="font-variant-ligatures: no-common-ligatures" class="">Minimizable</span><span style="font-variant-ligatures: no-common-ligatures; color: #839496" class=""> { // has to be final</span></div><p style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150); min-height: 15px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp;</span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> x: </span><span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">Int</span></div><p style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150); min-height: 15px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp;&nbsp; &nbsp;</span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">init</span><span style="font-variant-ligatures: no-common-ligatures" class="">(x: </span><span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">Int</span><span style="font-variant-ligatures: no-common-ligatures" class="">) {</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #d33682" class="">x</span><span style="font-variant-ligatures: no-common-ligatures" class=""> = x</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; }</span></div><p style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150); min-height: 15px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp;&nbsp; &nbsp;</span><br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">func</span><span style="font-variant-ligatures: no-common-ligatures" class=""> min(from other: </span><span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">A</span><span style="font-variant-ligatures: no-common-ligatures" class="">) -&gt; </span><span style="font-variant-ligatures: no-common-ligatures; color: #b58901" class="">A</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #d33682" class="">x</span><span style="font-variant-ligatures: no-common-ligatures" class=""> &lt; other.</span><span style="font-variant-ligatures: no-common-ligatures; color: #d33682" class="">x</span><span style="font-variant-ligatures: no-common-ligatures" class=""> ? </span><span style="font-variant-ligatures: no-common-ligatures; color: #859901" class="">self</span><span style="font-variant-ligatures: no-common-ligatures" class=""> : other</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">&nbsp; &nbsp; }</span></div><div style="margin: 0px; font-size: 13px; line-height: normal; font-family: Menlo; color: rgb(131, 148, 150);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div></div><div>Ceylon:</div><div><br class=""></div><div><pre style="background-color: rgb(255, 255, 255); font-family: Menlo;" class=""><span style="color:#4c4c4c;" class="">interface </span><span style="color:#990066;" class="">Minimizable</span>&lt;<span style="color:#990066;" class="">Other</span>&gt; <span style="color:#4c4c4c;" class="">of </span><span style="color:#990066;" class="">Other </span><span style="color:#4c4c4c;" class="">given </span><span style="color:#990066;" class="">Other </span><span style="color:#4c4c4c;" class="">satisfies </span><span style="color:#990066;" class="">Minimizable</span>&lt;<span style="color:#990066;" class="">Other</span>&gt; {<br class="">    <span style="color:#3399cc;" class="">shared formal </span><span style="color:#990066;" class="">Other </span><span style="color:#003399;" class="">min</span>(<span style="color:#990066;" class="">Other </span><span style="color:#003399;" class="">other</span>);<br class="">}<br class=""><br class=""><span style="color:#4c4c4c;" class="">class </span><span style="color:#990066;" class="">A</span>() <span style="color:#4c4c4c;" class="">satisfies </span><span style="color:#990066;" class="">Minimizable</span>&lt;<span style="color:#990066;" class="">A</span>&gt; {<br class=""><br class="">    <span style="color:#990066;" class="">Integer </span><span style="color:#003399;" class="">x </span>= <span style="color:#0000ff;" class="">0</span>;<br class=""><br class="">    <span style="color:#3399cc;" class="">shared actual default </span><span style="color:#990066;" class="">A </span><span style="color:#003399;" class="">min</span>(<span style="color:#990066;" class="">A </span><span style="color:#003399;" class="">other</span>) {<br class="">        <span style="color:#4c4c4c;" class="">if </span>(<span style="color:#003399;" class="">x </span>&lt; <span style="color:#003399;" class="">other</span>.<span style="color:#663399;" class="">x</span>) {<br class="">            <span style="color:#4c4c4c;" class="">return this</span>;<br class="">        } <span style="color:#4c4c4c;" class="">else </span>{<br class="">            <span style="color:#4c4c4c;" class="">return </span><span style="color:#003399;" class="">other</span>;<br class="">        }<br class="">    }<br class="">}<br class=""></pre><div class=""><br class=""></div><div class="">In Ceylon class A does not have to be final and choosing the minimum of two values would be available for values from the whole subtree of types rooted in A (the `of` ensures that such a declaration cannot „cross“ into other subtrees) whereas `Self` enforces that there is no subtree below class A.</div><div class=""><br class=""></div><div class="">I have to admit that I am not well versed using `Self`, yet, so maybe I’m wrong here. In addition I am sure that `Self` allows designs</div><div class="">that are not possible with Ceylon’s `of`.</div><div class=""><br class=""></div><div class="">The usage of Ceylon’s `of` for enumeration types is as follows (example taken from <a href="http://ceylon-lang.org/documentation/tour/types/" class="">http://ceylon-lang.org/documentation/tour/types/</a>):</div><div class=""><br class=""></div><div class=""><pre data-language="ceylon" class="with-editor" style="background-color: rgb(47, 30, 46); word-wrap: break-word; color: rgb(231, 233, 219); font-family: 'andale mono', 'lucida console', monospace; margin-top: 0px; margin-bottom: 0px; padding: 10px; border: 0px; font-size: 15px; vertical-align: baseline; line-height: 1.5;"><code class="rainbow" style="font-family: Inconsolata, Monaco, Courier, monospace; margin: 0px; padding: 0px; border: 0px; font-size: 14.5px; vertical-align: baseline; line-height: 1.5;"><span class="entity function" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(6, 182, 239);">abstract</span> <span class="keyword" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(184, 186, 175);">class</span> <span class="entity class" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(254, 196, 24);">Node</span>() <span class="keyword" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(184, 186, 175);">of</span> <span class="entity class" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(254, 196, 24);">Leaf</span> | <span class="entity class" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(254, 196, 24);">Branch</span> {}

<span class="keyword" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(184, 186, 175);">class</span> <span class="entity class" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(254, 196, 24);">Leaf</span>(<span class="entity function" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(6, 182, 239);">shared</span> <span class="entity class" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(254, 196, 24);">Object</span> <span class="global variable" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(239, 97, 85);">element</span>) 
        <span class="keyword" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(184, 186, 175);">extends</span> <span class="entity class" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(254, 196, 24);">Node</span>() {}

<span class="keyword" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(184, 186, 175);">class</span> <span class="entity class" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(254, 196, 24);">Branch</span>(<span class="entity function" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(6, 182, 239);">shared</span> <span class="entity class" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(254, 196, 24);">Node</span> <span class="global variable" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(239, 97, 85);">left</span>, <span class="entity function" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(6, 182, 239);">shared</span> <span class="entity class" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(254, 196, 24);">Node</span> <span class="global variable" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(239, 97, 85);">right</span>) 
        <span class="keyword" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(184, 186, 175);">extends</span> <span class="entity class" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(254, 196, 24);">Node</span>() {}</code></pre><div class=""><pre data-language="ceylon" class="with-editor" style="background-color: rgb(47, 30, 46); word-wrap: break-word; color: rgb(231, 233, 219); font-family: 'andale mono', 'lucida console', monospace; margin-top: 0px; margin-bottom: 0px; padding: 10px; border: 0px; font-size: 15px; vertical-align: baseline; line-height: 1.5;"><code class="rainbow" style="font-family: Inconsolata, Monaco, Courier, monospace; margin: 0px; padding: 0px; border: 0px; font-size: 14.5px; vertical-align: baseline; line-height: 1.5;"><span class="keyword" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(184, 186, 175);">void</span> <span class="global variable" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(239, 97, 85);">printTree</span>(<span class="entity class" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(254, 196, 24);">Node</span> <span class="global variable" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(239, 97, 85);">node</span>) {
    <span class="keyword" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(184, 186, 175);">switch</span> (<span class="global variable" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(239, 97, 85);">node</span>)
    <span class="keyword" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(184, 186, 175);">case</span> (<span class="keyword" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(184, 186, 175);">is</span> <span class="entity class" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(254, 196, 24);">Leaf</span>) {
        <span class="global variable" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(239, 97, 85);">print</span>(<span class="string" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(72, 182, 133);">"Found a leaf: ``</span><span class="global variable" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(239, 97, 85);">node</span>.<span class="variable instance" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(85, 227, 239);">element</span><span class="string" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(72, 182, 133);">``!"</span>);
    }
    <span class="keyword" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(184, 186, 175);">case</span> (<span class="keyword" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(184, 186, 175);">is</span> <span class="entity class" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(254, 196, 24);">Branch</span>) {
        <span class="global variable" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(239, 97, 85);">printTree</span>(<span class="global variable" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(239, 97, 85);">node</span>.<span class="variable instance" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(85, 227, 239);">left</span>);
        <span class="global variable" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(239, 97, 85);">printTree</span>(<span class="global variable" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(239, 97, 85);">node</span>.<span class="variable instance" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-family: inherit; vertical-align: baseline; color: rgb(85, 227, 239);">right</span>);
    }
}</code></pre><div class=""><br class=""></div></div></div><div class=""><br class=""></div></div><div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class="">which has lead to lengthy discussion threads about Self, StaticSelf,<br class="">#Self etc.).<br class=""><br class=""><blockquote type="cite" class="">Finally, in a<br class="">language with first-class value types, taking a protocol-oriented<br class="">approach to abstraction leads to *fundamentally* different designs from<br class="">what you get using OOP.<br class=""></blockquote><br class="">Eiffel has expanded types which are value types with copy semantics<br class="">quite like structs in Swift. These expanded types are pretty much<br class="">integrated into Eiffel's class-only type system. Just define a class<br class="">as `expanded` and you are done. <br class=""></blockquote><br class="">Unless this part of the language has changed since 1996, or unless I've<br class="">misread <a href="https://www.cs.kent.ac.uk/pubs/1996/798/content.pdf" class="">https://www.cs.kent.ac.uk/pubs/1996/798/content.pdf</a>, you can't<br class="">make an efficient array with value semantics in Eiffel. &nbsp;That, IMO,<br class="">cannot be considered a language with first-class value types.<br class=""></div></div></blockquote><div><br class=""></div>I haven’t had time yet to really evaluate that paper, but if you are right, then I agree</div><div>with you that Eiffel cannot be considered as having first-calss value types.</div><div><br class=""></div><div>At least one of the deficiencies listed in the paper does not exist anymore AFAIU&nbsp;</div><div>(expanded types not having constructors), though, so maybe things actually do have&nbsp;</div><div>changed since then.</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class="">Eiffel seems to have no need to introduce interfaces or protocols to<br class="">the language to support value types. &nbsp;<br class=""></blockquote><br class="">No, of course not. &nbsp;By saying that everything from abstract interfaces<br class="">to static constraints and even value types is to be expressed a kind of<br class="">possibly-generic class, you can eliminate distinctions in the language<br class="">that IMO help to clarify design intent. &nbsp;This is a language design<br class="">choice one could make, but not one I'd want to. &nbsp;In LISP, everything is<br class="">an S-expression. &nbsp;That has certain upsides, but for me it fails the<br class="">expressivity test.<br class=""></div></div></blockquote><div><br class=""></div><div>That’s certainly a valid point.</div><div><br class=""></div><div>Furthermore I do understand (and fully support) that being interoperable with Objective-C is an&nbsp;</div><div>important restriction on Swift’s design space and I think it is absolutely awesome how</div><div>that has been achieved!</div><div><br class=""></div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div class=""><br class=""><blockquote type="cite" class="">You can even derive from expanded classes which is currently not<br class="">possible in Swift but has already been discussed several times on this<br class="">mailing list. &nbsp;Polymorphic usage is only possible for non expanded<br class="">super types, which means as far as I understood that a reference is<br class="">used in that case. Variables with an expanded type do not use refences<br class="">and therefore may not be used polymorphically in Eiffel. &nbsp;This should<br class="">be similar in Swift, at least as far as I did understand it. The<br class="">question whether variables with a value type can be used<br class="">polymorphically currently does not arise in Swift as structs cannot<br class="">inherit from each other (yet?).<br class=""><br class=""><blockquote type="cite" class=""><br class=""><blockquote type="cite" class="">The more important distinction of Swift is emphasizing value types and<br class="">making mutation safely available by enforcing copy semantics for value<br class="">types. &nbsp;<br class=""></blockquote><br class="">We don't, in fact, enforce copy semantics for value types. &nbsp;That's<br class="">something I'd like to change. &nbsp;But regardless, value types would be a<br class="">*lot* less useful if they couldn't conform to protocols, and so they<br class="">would be a lot less used. &nbsp;Heck, before we got protocol extensions in<br class="">Swift 2, there was basically *no way* to share implementation among<br class="">value types. &nbsp;So you can't take protocols out of the picture without<br class="">making value types, and the argument for value semantics, far weaker.<br class=""></blockquote><br class="">Why? Like I said, Eiffel *has* value types without needing<br class="">protocols. They just have a unified mechanism built around classes.<br class=""></blockquote><br class="">Because I'm speaking about Swift, not some other world where Protocol ==<br class="">Generic Class ;-)<br class=""></div></div></blockquote><br class=""></div><div>Ah, ok, I took your statement of protocols being needed for strong value semantics</div><div>to be of general validity, not confined to Swift :-)&nbsp;</div><div>Within Swift that is certainly true!</div><div><br class=""></div><div>-Thorsten</div><div><br class=""></div><br class=""></div></div></div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>