<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 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><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=""><div class=""><div class=""><div class=""><div class=""><div class=""><br class=""></div><div class="">I don't think that this would be confusing since `where` indicates that the type is used in a more generic way.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">You've convinced me. I wanted to keep the generic syntax simple but having thought over it your proposal it much better in handling more complex cases without introducing additional syntax.</div><div class="">Also considering Swifts type inference where types with long names are easier to use.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">A "small" overview of several examples:</div><div class=""><br class=""></div><div class="">Using the former example of CollectionType which is used as a more concrete type (using a "leading dot" which is the same as `Self.`).</div><div class=""><br class=""></div><div class="">// These examples&nbsp;are only a demonstration of how you could&nbsp;use collection type</div><div class=""><br class=""></div><div class="">CollectionType&lt;where .Generator.Element == String, .Index == Int, .SubSequence: Self&gt;</div><div class=""><br class=""></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">CollectionType&lt;where .Generator.Element == String, .Index == Int&gt;</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">CollectionType&lt;where .Generator.Element == String&gt;</span></div><div class=""><br class=""></div><div class="">// if having `Element` as associated type</div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">CollectionType&lt;where .Element == String&gt;</span></div></div></div></div></div></div></div></blockquote><div><br class=""></div><div>One possible/fun option for syntax would be *if* Generics changed to have the types labelled. In that case, “where” becomes a keyword to distinguish a partial vs full constraint.&nbsp;</div><div><br class=""></div><div>For instance, Optional&lt;T == BooleanType&gt; would describe a concrete Optional holding some implementation of BooleanType, while Optional&lt;where T:BooleanType&gt; would be a generated protocol to umbrella every Optional that matches (e.g. Optional&lt;T == Bool&gt;, Optional&lt;T == ObjCBool&gt;, …)</div><div><br class=""></div><div>Then the syntax could be identical, e.g.&nbsp;RawRepresentable&lt;RawValue == Int&gt; vs RawRepresentable&lt;where RawValue:SignedNumberType&gt;</div><div><br class=""></div><div>For protocols with self requirements you would likely force “where” syntax. I can say Equatable&lt;Self == Int&gt;, but the protocol can *only* be implemented by one type in the system, Int. I can’t think of a reason to support this.</div><div><br class=""></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=""><div class=""><div class=""><div class=""><div class=""><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">// covariance and invariance</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">protocol A {}</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">extension Int: A {}</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><div class="">let intArray: [Int] = [1, 2, 3]</div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">let aArray: [A] = [1, 2, 3]</span></div></div></div></div></div></div></blockquote><div><br class=""></div>probably still:</div><div>&nbsp; let aArray: Array&lt;where .Element: Int&gt; = [1,2,3]&nbsp;</div><div><br class=""></div><div>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><br class=""></div><div>I could however see a way of doing</div><div><div>&nbsp; let aCovariantArray: Array&lt;where .Element: Int&gt; = [1,2,3]&nbsp;</div><div class="">&nbsp; let aArray = aCovaraintArray as [A]</div><div class=""><br class=""></div><div class="">being allowed, just as "intArray as [A]" works today due to internal behavior.</div><div class=""><br class=""></div></div><div>I detailed the ramifications of “is a concrete array of some specific implementation of A” behavior in the other half of my response - you are basically blocking a good deal of mutation behavior due to type safety. The restrictions are such that&nbsp;</div><div><br class=""></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=""><div class=""><div class=""><div class=""><div class=""><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">var col1: CollectionType&lt;where .Element == A&gt;</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">col1 = intArray // doesn't work since Int != A</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">col1 = aArray // obviously works</span></div></div></div></div></div></div></blockquote><div><br class=""></div><div>The last line actually will fail as well if aArray is covariant on Element being A.</div><div><br class=""></div><div>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><br class=""></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=""><div class=""><div class=""><div class=""><div class=""><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">var col2: CollectionType&lt;where .Element: A&gt;</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">// both work since `Int` and `A` conform to `A` (currently in Swift 2.2&nbsp;`A` does<span class="Apple-converted-space">&nbsp;</span><b class=""><u class="">not</u></b><span class="Apple-converted-space">&nbsp;</span>conform to `A`, I don't know if this is a feature)</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">col2 = intArray</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">col2 = aArray</span></div></div></div></div></div></div></blockquote><br class=""></div><div>Yep!</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=""><div class="">// with a concrete type using the example above:</div><div class=""><br class=""></div><div class="">// replace type of `col1` with (all replacements are equivalent)</div><div class="">`Array&lt;A&gt;` or<span class="Apple-converted-space">&nbsp;</span><span style="background-color: rgba(255, 255, 255, 0);" class="">`Array&lt;where .Element == A&gt;` or&nbsp;`[A]` or&nbsp;`[where .Element == A]`</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><div class=""><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">// replace type of `col2` with (all replacements are equivalent)</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class="">`Array&lt;where .Element: A&gt;` or&nbsp;`[where .Element: A]`</span></div></div></div></div></div></div></div></blockquote><div><br class=""></div>I think yes, although col1 = aArray will still fail :D</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=""><div class="">// to be discussed: using many protocols together with protocol&lt;&gt;</div><div class=""><br class=""></div><div class="">// declaring a generic type T which is used in two protocols</div><div class="">protocol&lt;where T, Self: SequenceType&lt;where .Element == T&gt;, Self: Indexable&lt;where .Index == T&gt;&gt;</div><div class=""><br class=""></div><div class="">// although in this case it can be written as</div><div class="">SequenceType&lt;where T, .Element == T,<span class="Apple-converted-space">&nbsp;</span><span style="background-color: rgba(255, 255, 255, 0);" class="">Self: Indexable&lt;where .Index == T&gt;&gt;</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br class=""></span></div><div class="">Even though the latter one is shorter I'm skeptical about using `Self:` in protocol where clauses since at a first glance it implies that the type is only a `SequenceType`.</div></div></div></div></div></div></blockquote><div><br class=""></div><div>protocol&lt;&gt; is there for describing multiple protocols, so I’d go for the 1st.</div><div><br class=""></div><div>-DW</div></div><br class=""></body></html>