<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 26, 2016, at 10:32 AM, 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="">Am 26.01.2016 um 00:27 schrieb David Waite &lt;<a href="mailto:david@alkaline-solutions.com" class="">david@alkaline-solutions.com</a>&gt;:<br class=""></div><blockquote type="cite" 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=""><br class=""></div><blockquote type="cite" class=""><div class="" 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;"><div class=""><div class=""><div class=""><div class=""><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">// covariance and invariance</span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">protocol A {}</span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">extension Int: A {}</span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="">let intArray: [Int] = [1, 2, 3]</div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">let aArray: [A] = [1, 2, 3]</span></div></div></div></div></div></div></blockquote><div class=""><br class=""></div>probably still:</div><div class="">&nbsp; let aArray: Array&lt;where .Element: Int&gt; = [1,2,3]&nbsp;</div><div class=""><br class=""></div><div class="">if you really want covariance. The limitations (detailed in the other email reply) are such that it is better to have clear syntax so people recognize there may be ramifications.</div></div></blockquote><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="">I don't want implicit/inferred covariant types.</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="">In this case invariant array:</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=""><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=""><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">let aArray: Array&lt;where .Element == A&gt; = [1,2,3]&nbsp;</span></font></div></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=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">// which is equivalent to</span></font></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=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">let aArray: [A] = [1,2,3]&nbsp;</span></font></div></div></div></blockquote><div><br class=""></div>Ahh ok, you are asking for an invariant array of A’s, then. Method calls and properties may have covariant properties (such as assignment allowing any subclass of A), but the representation of Array internally is always of a list of A protocol instances.</div><div><br class=""></div><div>A covariant _constraint_ is instead saying that you are referencing one of many different possible concrete Array types - some array based around internally having a list of A, or an array based around some particular subtype of A.&nbsp;</div><div><br class=""></div><div>This will generally be restricted further for safety reasons. For example, a subscript assignment would first cast up to A, then have to cast down to some particular subtype of A. That downcast is unsafe and may fail based on the concrete kind of array behind the protocol.</div><div><br class=""></div><div><blockquote type="cite" class=""><div class=""><blockquote type="cite" 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=""><blockquote type="cite" class=""><div class="" 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;"><div class=""><div class=""><div class=""><div class=""><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">var col1: CollectionType&lt;where .Element == A&gt;</span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">col1 = intArray // doesn't work since Int != A</span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">col1 = aArray // obviously works</span></div></div></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">The last line actually will fail as well if aArray is covariant on Element being A.</div><div class=""><br class=""></div></div></div></blockquote><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="">"aArray" is not covariant to "intArray" although each element is covariant to any type which conforms to "A”.</div></div></blockquote><div><br class=""></div><div>I think we may be working through the communication issue. But basically:</div><div><div class=""><div class=""><br class=""></div></div></div></div><div><div><div class=""><div class="">let aArray: Array&lt;where .Element: A&gt; = [1,2,3]&nbsp;</div></div></div></div><div><div><br class=""></div><div>is specifying a type formed by a covariant constraint on Element. This means this could be a concrete array of A’s, or one of Ints, or one of some other implementation of A.</div><div><br class=""></div><div>So lets name them explicitly:</div><div><br class=""></div><div><span style="background-color: rgba(255, 255, 255, 0);" class="">var col1: CollectionType&lt;where .Element == A&gt;</span></div><div><span style="background-color: rgba(255, 255, 255, 0);" class="">let xArray:[Int] = [1,2,3]</span></div><div><span style="background-color: rgba(255, 255, 255, 0);" class="">let yArray:[A] = [1,2,3] // an Array of&nbsp;‘A's</span></div><div><br class=""></div><div><span style="background-color: rgba(255, 255, 255, 0);" class="">col1 = xArray // fails</span></div><div><span style="background-color: rgba(255, 255, 255, 0);" class="">col1 = yArray // succeeds</span></div><div><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><div><div><span style="background-color: rgba(255, 255, 255, 0);" class="">let zxArray:Array&lt;where .Element:A&gt; = xArray // similar to defining a protocol implicitly for arrays of A or of A-subtypes, of which [Int] conforms</span></div><div><div><span style="background-color: rgba(255, 255, 255, 0);" class="">let zyArray:Array&lt;where .Element:A&gt; = yArray // same for [A]</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div></div></div><div><span style="background-color: rgba(255, 255, 255, 0);" class="">col1 = zxArray // fails</span></div><div><span style="background-color: rgba(255, 255, 255, 0);" class="">col1 = zyArray // still fails</span></div><div><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><div><span style="background-color: rgba(255, 255, 255, 0);" class="">Even though dynamically the zyArray type is compatible, the compiler is reasoning statically that zxArray and zyArray both could be non-working types, and therefore must be blocked for safety reasons.</span></div><div><br class=""></div><blockquote type="cite" class=""><div class=""><blockquote type="cite" 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="">CollectionType “col1” is being constrained by Elements which *are* A, while aArray is a Collection type which is constrained by Elements being A *or* any subtype. if “intArray” doesn’t work directly and isn’t safe to work directly, why would discarding some of its type information by assigning to aArray make a difference?&nbsp;</div></div></div></blockquote><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="">I was inspired from the current generic system of functions:</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=""><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="">func takeCollection&lt;C: CollectionType where C.Generator.Element == A&gt;(c: C) {}</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=""><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="">takeCollection(intArray) // fails</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="">takeCollection(aArray) &nbsp;// works</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=""><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=""><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="">Or how would you interpret "<span style="background-color: rgba(255, 255, 255, 0);" class="">CollectionType&lt;where .Element == A&gt;" in contrast to "CollectionType&lt;where .Element: A&gt;”?</span></div></div></blockquote><div><br class=""></div>I think we had a confusion issue about whether A was an invariant or covariant constraint in the post I was responding to. I’m assuming now that you actually did mean it to be invariant.</div><div><br class=""><blockquote type="cite" class=""><div class=""><blockquote type="cite" 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="">protocol&lt;&gt; is there for describing multiple protocols, so I’d go for the 1st.</div></div></div></blockquote><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="">+1 For using the first</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=""><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="">Suggestion:</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="">separate declaration of T to make it consistent with current generic syntax</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=""><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=""><div class=""><div class=""><div class=""><div class=""><div class=""><div class=""><font class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">protocol&lt;T where Self: SequenceType&lt;where .Element == T&gt;, Self: Indexable&lt;where .Index == T&gt;&gt;</span></font></div><div class=""><br class=""></div><div class="">This example could also be rewritten to:</div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">protocol&lt;where Self: SequenceType, Self: Indexable, Self.Element == Self.Index&gt;</span></div></div></div></div></div></div></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=""><br class=""></div></div></blockquote><div><br class=""></div>How about&nbsp;</div><div><br class="">protocol&lt;SequenceType, Indexable where .Element == .Index&gt;</div><div><br class=""></div><div>-DW</div><div><br class=""></div></body></html>