<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div></div><div><br></div><div><br>Am 25.01.2016 um 23:58 schrieb David Waite &lt;<a href="mailto:david@alkaline-solutions.com">david@alkaline-solutions.com</a>&gt;:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8"><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 25, 2016, at 2:52 PM, Maximilian Hünenberger &lt;<a href="mailto:m.huenenberger@me.com" class="">m.huenenberger@me.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span class=""></span></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><span class=""></span></div><div class=""><div class=""><span class=""></span></div><div class=""><div class=""><span class=""></span></div><div class=""><div class=""><span class=""></span></div><div class=""><div class=""></div><div class="">Am 22.01.2016 um 21:41 schrieb David Waite &lt;<a href="mailto:david@alkaline-solutions.com" class="">david@alkaline-solutions.com</a>&gt;:</div><blockquote type="cite" class=""><div class=""><div class="">Since today equatable mandates a defined, public == method, and I think the generic is always loses to that specificity. You don’t even need dynamic casting, because your generic version only gets called when there isn’t a non-generic version.</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class=""><div class="">// in this case there could be a more general == function</div></div></div><div class=""><div class=""><div class="">func == &lt;T: Equatable, U: Equatable&gt;(x: T, y: U) -&gt; Bool {</div></div></div><div class=""><div class=""><div class="">&nbsp; &nbsp; return false</div></div></div><div class=""><div class=""><div class="">}</div></div></div></blockquote><div class=""><div class=""><div class=""><div class=""><br class=""></div></div></div></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class="">1 == 1 // true</div><div class="">1 == “1” // false</div></blockquote><div class=""><br class=""></div></div></blockquote><div class=""><br class=""></div><div class="">I thought also of this example:</div><div class=""><br class=""></div><div class=""><div class=""><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">let a: Equatable = 1</span></font></div><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">let b: Equatable = 2</span></font></div><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></font></div><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">a == b // would fail in your case</span></font></div></div></div></div></div></div></div></div></div></blockquote><div><br class=""></div>I was speaking of today - today you can’t express "let a:Equatable = 1”.</div></div></blockquote><div><br></div><div>Oh, ok I haven't seen the "today".</div><br><blockquote type="cite"><div><div><br class=""><blockquote type="cite" class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class=""><div class=""><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class=""><div class=""><div class=""><br class=""></div>In that, the covariant case, Array&lt;Element:Number&gt; is _different_ than Array&lt;Number&gt; today.</div><div class=""><br class=""></div><div class="">Today, Array&lt;Number&gt; and Array&lt;Int&gt; are different concrete types. One deals in terms of Numbers, and one in terms of Ints. They are structured in memory different, etc.</div><div class=""><br class=""></div><div class="">When I say partial constraints, applied to generics in this case (reluctantly), I’m saying the following:</div><div class=""><br class=""></div><div class="">Implicitly define a protocol around all concrete Array instances where Element is defined to be Number or a subtype of Number, exposing all methods, properties, etc which are safe.</div><div class=""><br class=""></div><div class="">Safety rules are equivalency rules here: If a method or property returns Element, I can say that it is safe to represent the result of “var first:Element {get}” as a Number, because in the cases where it returns a subtype like Int, I can still safely upcast to Number. I have a safe and uniform interface.</div><div class=""><br class=""></div><div class="">If a method takes an argument or for any property setter, I have to require Element to be invariant. Modifying the first item of an array isn’t safe, because I might try to assign an Int value when really its a UInt8 array.</div></div></div></blockquote><div class=""><br class=""></div><div class="">Why Element has to be invariant?</div><div class=""><br class=""></div><div class="">let uintArray: [UInt8] = [1]</div><div class="">var covariantArray: [Number] =<span class="Apple-converted-space">&nbsp;</span><span style="background-color: rgba(255, 255, 255, 0);" class="">uintArray</span></div><div class="">// this doesn't cause an error since Int is also a Number</div><div class="">covariantArray[0] = Int(36754)</div></div></div></div></div></div></blockquote><div><br class=""></div>A generic instance is still a concrete type, so for instance:</div><div>- Array&lt;.Element == Int&gt; is a concrete type, will store Int value types internally (e.g. sizeof(Int) == 8), and the API will allow you to subscript get and set Int values,etc</div><div>- Array&lt;.Element == Any&gt; is a concrete type, will store Any protocol references internally (e.g. sizeof(Any) == 32), and the API will allow you to subscript get and set Any values,etc</div><div>- a new Array&lt;.Element:Any&gt; is a protocol type, refers to/boxes any concrete Array without regards to its internal member (e.g. element size varies), and the API might allow you to subscript get Any because it can upcast all type instances to Any, but will hide the ability to set Any. The type system can’t be sure the concrete type you are supplying is appropriate for the actual Element type of the concrete Array (without changes in that feature as well, subscript must get and set, so the subscript get would also be hidden)</div><div><br class=""></div><div><div>Per your proposed syntax, your set above would need to fail at compile-time or will fail at runtime, because covariantArray is a protocol boxing a copy of the [UInt8]-based uInt8Array, without additional behavior.</div><div class=""><br class=""></div></div><div>You could define a process where a Array&lt;.Element == Number&gt; is created by the compiler in that situation off of the uintArray value and assigned into covariantArray before the assignment happens, but thats a very expensive action to take implicitly, would require a dynamic check on each access. Plus, that would fail for generic types which were classes instead of value type (because you would only be updating a single reference to point to the new object)</div></div></blockquote><div><br></div><div>To have an implicit array of type Array&lt;Number&gt; that's what I've thought.</div><div><br></div><div>I see your point but since covariance and contra-variance is a big topic there is a thread which discusses this in more detail:</div><div><br></div><div>Make generics covariant - was: [swift-evolution] Make generics covariant and add generics to protocols</div><br><blockquote type="cite"><div><div><br class=""></div><div>&lt;snip, to respond later&gt;</div><div><blockquote type="cite" class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">PS: Have you made a formal proposal already?</div></blockquote></div><br class=""><div class="">Not yet, I was hoping to get more feedback on the value of the idea before writing up all of the rules, which will take many hours of my time (to fail fast). There has been very little discussion so far.</div><div class=""><br class=""></div><div class="">My hope is to have a discussion on where the generics and constrained protocol systems should go for Swift 3 and beyond, but I suspect the core team is occupied by Swift 2.2 and the API guidelines discussion ATM. Type system changes are IMHO something that really warrant having a roadmap extending several releases into the future, and there are a number of ones being proposed by both the core team and evolution members (evolutioneers?) in general.</div><div class=""><br class=""></div><div class="">-DW</div></div></blockquote><br><div>We'll see. At least a better generics system is one of the main goals for Swift 3.</div><div><br></div><div>- Maximilian</div></body></html>