<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Please split this in smaller pieces. Nobody will want to discuss all of it at once.</div><br class=""><div class="">
<span class="Apple-style-span" style="border-collapse: separate; line-height: normal; border-spacing: 0px;">Félix</span>
</div>

<br class=""><div><blockquote type="cite" class=""><div class="">Le 30 déc. 2015 à 17:50:44, Howard Lovatt via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; a écrit :</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div dir="auto" class=""><div class=""><div class="" style="margin: 0px; line-height: normal;"><font class="" style="background-color: rgba(255, 255, 255, 0);">Proposal: Protocols on Steroids</font></div><div class="" style="margin: 0px; line-height: normal;"><font class="" style="background-color: rgba(255, 255, 255, 0);">=======================</font></div><div class="" style="margin: 0px; line-height: normal;"><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font></div><div class="" style="margin: 0px; line-height: normal;"><font class="" style="background-color: rgba(255, 255, 255, 0);">Change the way protocols and generics work, in particular:</font></div><div class="" style="margin: 0px; line-height: normal;"><ol class=""><li class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">Generic protocol with type parameters inside `&lt;&gt;`, like classes and structs</span></li><li class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">Allow covariant return types including for generic types</span></li><li class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">Allow covariant generic argument types with a runtime check that it is of the correct type</span></li><li class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">Treat Self as a shorthand for the type name; in particular as&nbsp;though&nbsp;there was an extra genetic type, `Type&lt;Self: Type&gt;` and everywhere `Self` appeared in the body the&nbsp;compiler&nbsp;substitutes `Type`</font></li><li class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">Allow `GenericTypeName.dynamicType` to return the metatype of a generic type</span></li><li class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">Treat typealias as introducing a generic type parameter that is not part of the type's type signature (or whatever it is renamed to)</span></li><li class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">Allow implementations in protocols as well as in extensions to protocols (I think this is on the cards already)</span></li><li class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">Allow default stored properties and default inits in protocol, see `Holder` example below</span></li><li class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">Disallow overload of a function with a generically typed argument with a function whose argument is&nbsp;derived&nbsp;from the generic type, must be an override.</font></li></ol><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">Implications</font></div><div class="">------------</div><div class=""><ol class="MailOutline"><li class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">Arrays and a like become covariant (with runtime type check for write) - like Java arrays but not Java Lists</span></li><li class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">`Equatable` and co would not be a special type, could have arrays of `Equatable`s</font></li><li class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">No need for `AnyXXX` types, the protocol does this directly</font></li><li class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">No need for `CollectionType` and `Array`, `Array` would become a `protocol` and a `struct`</font></li></ol><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">Example</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">--------</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">A holder of 1 value (chosen to keep the example short - think of it as an array):</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; protocol Holder&lt;T&gt; {</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; &nbsp; &nbsp; default var value: T // See implementation below for what default does</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; }</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">In use it could be used like:</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; var holder = Holder(value: 1) // Holder&lt;Int&gt;</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; func printout(value: Holder&lt;Any&gt;) {</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; &nbsp; &nbsp; print("\(value.value)")</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; }</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; printout(holder) // Passing a Holder&lt;Int&gt; to a Holder&lt;Any&gt; OK</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">Implementation</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">----------------</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">The above example would be translated by the compiler to something like (though the names would be changed - names chosen to spell out what is happening):</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp;&nbsp;</font><span style="background-color: rgba(255, 255, 255, 0);" class="">protocol Holder&lt;T&gt; { // Retains generic type because protocols are types</span></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; &nbsp; &nbsp; var value: T { get set }</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; }</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; struct DefaultHolder&lt;T&gt;: Holder&lt;T&gt; { // Written because protocol had a default implementation</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; &nbsp; &nbsp; var value: T</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; }</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font></div><div class=""><font class=""><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; struct HolderInt: DefaultHolder&lt;Int&gt; { // Written because a `Holder&lt;Int&gt;` was created</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; &nbsp; &nbsp; var _value: Int</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; &nbsp; &nbsp; var value: Int {</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get {</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return _value</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set {</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let temp = newValue as! Int // Runtime type check for write</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _value = temp</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">&nbsp; &nbsp; }</font></div></font></div><div class=""><div class=""><br class=""></div></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></font></div></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">Other languages</font></div><div class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">-----------------</font></div></div><div class="" style="margin: 0px; line-height: normal;"><div class=""><ol class="MailOutline"><li class=""><font class="" style="background-color: rgba(255, 255, 255, 0);">This is how Java arrays work, but not Java generics which are cumbersome to use in practice but do offer static type checking on write which neither this proposal or Java arrays offer. Java arrays use a runtime type check.</font></li><li class="">Dynamic languages and Obj-C normally allow you to store anything in an array (NSArray). This is different than the behaviour proposed, an array would be covariant, i.e. a `[Hashable]` could store anything derived from `Hashable` but could not store an `Equatable` or an `Any` that were not `Hashable`. But the array could be passed to a function expecting an `[Any]`, for example, and that function could read from the array.</li></ol></div></div></div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=iRI3beHTe3UxYAHTlV3lA38zIPfHMhyuRzgTmGKV6k420DPIzqosw14JMxafouSR-2BlVXevrqYNk7IZfzm2RWFTLgU-2B4OlQUaZgNeu3D9QbCOsIlUOlx2Gu0FlCBf2v3p6ws8iiOoVEMOCabXB54QThBe8N5P53E-2BJ-2BbzHVvNrgn9h8ck3Fsm15bgtYJ-2FWAi1JPvqs9DS7KkEL344BdKWZCLu-2BEuRVDX1bLdYI-2F0IpUU-3D" alt="" width="1" height="1" border="0" style="height:1px !important;width:1px !important;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !important;margin-right:0 !important;margin-left:0 !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;" class="">
</div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>