<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div></div><div><br></div><div>Am 22.01.2016 um 03:05 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 21, 2016, at 1:29 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=""><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=""><span style="background-color: rgba(255, 255, 255, 0);" class="">I think we could make&nbsp;ConcreteThing&lt;…&gt; and&nbsp;ProtocolType&lt;…&gt; equal in terms of generic syntax (which could be "redefined" as I proposed). Where you can also omit generic parameters for example in dictionary:</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=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br 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=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Dictionary&lt;Key: _ , Value: String&gt;</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=""><span style="background-color: rgba(255, 255, 255, 0);" class="">// or short form</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=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Dictionary&lt; _ , String&gt;</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=""><span style="background-color: rgba(255, 255, 255, 0);" class="">// even shorter</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=""><span style="background-color: rgba(255, 255, 255, 0);" class="">[ _ : String]</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=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br 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=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Where the Key of Dictionary is of any type which conforms to `Hashable`.</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=""><span style="background-color: rgba(255, 255, 255, 0);" class=""><br 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=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Note:&nbsp;`Hashable` is self constrained and behaviors of an<span class="Apple-converted-space">&nbsp;</span><b class="">any</b><span class="Apple-converted-space">&nbsp;</span>type of a self constrained protocol has to be discussed.</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=""><span style="background-color: rgba(255, 255, 255, 0);" class="">Second note: This is probably a bad example in terms of usability but it should only show the similar generic syntax (see my proposal).</span></div></div></blockquote><div><br class=""></div>I mentally treat self as an associated type bound to the first concrete subtype in the type chain. (first, because of class inheritance).&nbsp;</div></div></blockquote><div><br></div><div>Since Hashable is only self constrained due to Equatable should we even allow this code?</div><div><br></div><div>let a: Equatable = 1</div><div>let b: Equatable = "2"</div><div><br></div><div>a == b</div><div><br></div><div>// in this case there could be a more general == function</div><div>func == &lt;T: Equatable, U: Equatable&gt;(x: T, y: U) -&gt; Bool {</div><div>&nbsp; &nbsp; if let yAsT = y as? T {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return yAsT == x }</div><div>&nbsp; &nbsp; return false</div><div>}</div><div><br></div><div>But it seems like that there has to be a different implementation of `self` constrained functions (like ==) if a self constrained protocol is used without specifying `self`.</div><br><blockquote type="cite"><div><div><br class=""></div><div>Re: syntax, like I said I’m trying to defer too much syntax discussion until there is more participation/interest in the concept and approach (I think only four people have participated in this thread over nearly two weeks).&nbsp;</div><div><br class=""></div><div>But I’ll bite :-)</div><div><br class=""></div><div>It appears you are proposing that generics be expanded to be keyed either by generic type parameter name or positionally and adding _ to positional syntax, while I imagine protocols would remain just keyed by name.</div></div></blockquote><div><br></div><div>What do you mean by:</div><br><blockquote type="cite"><div><div>Protocols would not have a simplistic order to implement (for example, I could be extending two parent protocols, both with their own associated types)</div><div><br class=""></div></div></blockquote><div><br></div><div>Do you mean conforming to a protocol by "extending"?</div><div>In this case it would be even more explicit about types:</div><div><br></div><div>struct Numbers: SequenceType&lt;Element: Int, SubSequence: Numbers&gt; { ... }</div><div><br></div><div><br></div><div>To be clear, I'm proposing:</div><div>- Generic syntax for all types including protocols to be the same</div><div>- Named generic parameters eg: Array&lt;Element: Int&gt; &nbsp;, &nbsp;CollectionType&lt;Element: String, Index: Int&gt;</div><div>- Without name: <span style="background-color: rgba(255, 255, 255, 0);">Array&lt;Int&gt; &nbsp;, &nbsp;CollectionType&lt;String, Int&gt;</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">- Introduce "_" as placeholder for a covariant "any type" to make protocols and other generic types partially constrained:</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">Array&lt;Element: _ &gt; &nbsp;, &nbsp;CollectionType&lt;Element: String, Index: _ &gt;</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">which is the same as</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">Array&lt; _ &gt; &nbsp;, &nbsp;CollectionType&lt;String, _ &gt; ==&nbsp;CollectionType&lt;String&gt; ==&nbsp;CollectionType&lt;Element: String&gt;</span></div><div><br></div><br><blockquote type="cite"><div><div><blockquote type="cite" class=""><div class="">// for a concrete index of type Int</div><div class="">protocol&lt;<span class="" style="background-color: rgba(255, 255, 255, 0);">CollectionType where .Index == Int&gt;</span></div><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></div><div class="">What do you think about my proposed syntax ?</div><div class=""><br class=""><div class=""><font class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">CollectionType&lt;Index: Int&gt;</span></font></div></div></blockquote><div class=""><div class=""><div class=""><font class=""><span class="" style="background-color: rgba(255, 255, 255, 0);"><br class=""></span></font></div><div class=""><font class=""><span class="" style="background-color: rgba(255, 255, 255, 0);">I personally think there is a bit too much overlap between ‘where’ syntax, and possibly conflicting usage.&nbsp;</span></font><span style="background-color: rgba(255, 255, 255, 0);" class="">In your example, would Index: Foo indicate that index is exactly Foo, is Foo or some subtype, or is a concrete implementation of Foo? If there were two syntaxes, I’d hope one to be a much closer shortening of the other.</span></div></div></div></div><div><br class=""></div></div></blockquote><div><br></div><div><div class=""><div class=""><div class=""><span class="" style="background-color: rgba(255, 255, 255, 0);"><font color="#000000">Index: Foo</font></span></div><div class="">Index is of type Foo or a Subtype.</div><div class=""><br></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);"><span class="">- If Foo is a struct or a enum,&nbsp;</span>Index can be of type:&nbsp;Foo or a subtype e.g. Foo&lt;Int&gt; and Foo&lt; _ &gt;</span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div class=""><span style="background-color: rgba(255, 255, 255, 0);"><span class="">- If Foo is a protocol or a class,&nbsp;</span>Index can be of type (additionally to the ones above): subtypes e.g.&nbsp;Subclass&lt;Int&gt; , Subclass&lt; _ &gt; and Int if Int is of type Foo</span></div></div></div></div><br><blockquote type="cite"><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=""><div class="">Finally and to a lesser degree, the parameters for a generic type define a single concrete type, while for a protocol it defines a view of some concrete type. Today I can intuit Foo&lt;String&gt; is the name of a concrete type. During proposal, there was more value in having a placeholder syntax that did not damage intuition about concrete types.</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="">What do you mean by "<span style="background-color: rgba(255, 255, 255, 0);" class="">intuition about concrete types</span>” ?</div></div></blockquote><div><br class=""></div><div>Today, you cannot use generics except to declare or talk about a specific concrete type with a specific implementation and behavior - you know you are dealing with a concrete, initializable Foo&lt;Int&gt;. Among other things, you know that the full published API for Foo&lt;Int&gt; is available.</div><div><div><br class=""></div><div><div>From my perspective, Foo has an implicitly declared protocol. It is a protocol tied to a single implementation (or to subtypes which inherit and override that implementation, in the case of classes).</div><div><br class=""></div><div>This proposal (excluding type-opening) is about being able to use a protocol with associated types more loosely. My approach is to expose the methods which can be expressed safely and uniformly based on the type constraints available, and to hide the rest. Today, you would have to do this by declaring a new protocol and using extensions to opt concrete types into it, by using generic constraints exclusively, and/or using wrapper types like AnySequence to do type erasure.</div><div class=""><br class=""></div></div></div><blockquote type="cite" class=""><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="">Why not allowing Foo&lt; _ &gt; (to be for instance a covariant type to all Foo) ? It's similar to a protocol, but it is a more concrete type where you don't have to define a protocol to use Foo as a standalone type in a more general way.&nbsp;</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><div><br class=""></div><div><div>I do have a mild personal conflict around whether exposing the ability to have partially constrained generics is a good idea, but I admit my hesitation is based on philosophies of good application and API design, and not based on language design.</div><div><br class=""></div><div>&nbsp;implicit protocols on types seem pragmatic, because otherwise I’d have to create a protocol just for others to use me.&nbsp;</div><div><br class=""></div><div>Allowing a protocol with associated types to be partially constrained seems pragmatic to me, since otherwise I have to use one of the workarounds above (hand-coded new protocol, generic constraints ever, and/or type-erasure struct-wrapper).</div><div><br class=""></div><div>Expanding the usage of the implicit protocol on some generic type seems anti-pragmatic, just because it allows someone to go longer before they really evaluate whether locking consumers of their API into a single implementation is a good idea. They can always declare a protocol explicitly if they want partially constrained behavior.</div></div></div></div></div></blockquote><div><br></div><div>That was also my concern since I want to keep the generic syntax consistent with protocols. So maybe we could make it the same in case of generic parameter names but without the "_" so there are no protocol like behaviors for generic types.</div><div><br></div>Even though it would be nice to have a covariant Array&lt; _ &gt; type.<div>Talking about covariance how about (protocol Test {} , Int conforms to Test) a covariant Array&lt;Element: Test&gt; to Array&lt;Int&gt; and an invariant Array&lt;Test&gt;?</div><div><br></div><div>- Maximilian<br><blockquote type="cite"><div><div><div><div><div><br class=""></div><div>-DW</div><div><br class=""></div></div></div></div></div></blockquote></div></body></html>