<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div></div><div>See inline</div><div><br>Am 19.01.2016 um 19:47 schrieb David Waite <<a href="mailto:david@alkaline-solutions.com">david@alkaline-solutions.com</a>>:<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 19, 2016, at 7:49 AM, Maximilian Hünenberger <<a href="mailto:m.huenenberger@me.com" class="">m.huenenberger@me.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class="">I like the idea to use <font color="#bb2ca2" face="Menlo" class=""><span style="font-size: 11px;" class="">protocol</span></font><span style="font-family: Menlo; font-size: 11px;" class=""><> </span>for an abstraction with many constrained protocols but for a single type constraint it is a bit verbose.</div></div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><br class=""></div><div class="">What about generics in protocols which are only a view to its associated types or generics which create/are associated types?</div></div></div></div></blockquote><div><br class=""></div><div>Since I imagine reusing generics syntax for constraining protocols will be a popular proposal, I figure I’ll give the reasoning I personally didn’t use, at it for my initial placeholder syntax.</div><div><br class=""></div>The main reason l chose an alternate syntax was that generic type usage and protocol constraints aren’t expressed the same way - protocol constraints on associated types aren’t positional and can be missing. This meant that ConcreteThing<…> and ProtocolType<…> would have different syntaxes inside the angle brackets, and thus felt like it would promote more syntax bike shedding (in addition to personally seeming less clean to me). </div><div><br></div></div></blockquote><blockquote type="cite"><div><div>Using ProtocolType<…> syntax would I believe be the 5th syntactic usage for <...> (generic type declaration, generic type use, generic constraints on methods, protocol union and now generic protocol use). Swift gets away with the multiple usages today because the syntax within the angle brackets is very similar. Expanding protocol unions meant I stayed closer to generic constraint syntax, while still having was only four syntactic usages (as in, protocol unions would umbrella under/into partial protocol constraints as a new existential type redefinition “thing")</div><div><br class=""></div></div></blockquote><div><br></div><div><span style="background-color: rgba(255, 255, 255, 0);">I think we could make ConcreteThing<…> and ProtocolType<…> 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><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div><span style="background-color: rgba(255, 255, 255, 0);">Dictionary<Key: _ , Value: String></span></div><div><span style="background-color: rgba(255, 255, 255, 0);">// or short form</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">Dictionary< _ , String></span></div><div><span style="background-color: rgba(255, 255, 255, 0);">// even shorter</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">[ _ : String]</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div><span style="background-color: rgba(255, 255, 255, 0);">Where the Key of Dictionary is of any type which conforms to `Hashable`.</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div><span style="background-color: rgba(255, 255, 255, 0);">Note: `Hashable` is self constrained and behaviors of an <b>any</b> type of a self constrained protocol has to be discussed.</span></div><div><span style="background-color: rgba(255, 255, 255, 0);">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><br><blockquote type="cite"><div><div><div>As an example, the liberties I took with SequenceType took it down to a single associated type, but CollectionType would still have a minimum of Index and Element. I would need to declare CollectionType<where .Index == Index> or similar if I were wishing to partially constrain just one parameter. This is also eliminates most of the typing savings of using generic type usage syntax.</div></div></div></blockquote><div><br></div><div>I thought the proposed syntax would be:</div><div><br></div><div>// for a concrete index of type Int</div><div>protocol<<span style="background-color: rgba(255, 255, 255, 0);">CollectionType where .Index == Int></span></div><div><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div>What do you think about my proposed syntax ?</div><div><br><div><font color="#000000"><span style="background-color: rgba(255, 255, 255, 0);">CollectionType<Index: Int></span></font></div></div><br><blockquote type="cite"><div><div><div class=""><br class=""></div></div><div><div>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<String> 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><br class=""></div></div></div></blockquote><div><br></div><div>What do you mean by "<span style="background-color: rgba(255, 255, 255, 0);">intuition about concrete types</span>" ?</div><div>Why not allowing Foo< _ > (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. </div><div><br></div><div>- Maximilian</div><br><blockquote type="cite"><div><div><div class="">-DW</div><div class=""><br class=""></div></div><div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><br class=""></div><div class="">Example of a simple protocol which models a node of a tree:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);">// Before</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);">// NodeType can be anything</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);">// currently Swift doesn't allow</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);">// `typealias NodeType: Node`</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);">//</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);">// or even where clauses </div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);">// `typealias NodeType: Node where NodeType.T == T`</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);">protocol<span class="" style=""> Node {</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);"><span class="" style=""><span class="Apple-tab-span" style="white-space: pre;">        </span></span>typealias<span class="" style=""> T</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="" style="color: rgb(187, 44, 162);">typealias</span> NodeType</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><br class="webkit-block-placeholder"></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="" style="color: rgb(187, 44, 162);">var</span> value: <span class="" style="color: rgb(112, 61, 170);">T</span> { <span class="" style="color: rgb(187, 44, 162);">get</span> }</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="" style="color: rgb(187, 44, 162);">var</span> nodes: [<span class="" style="color: rgb(112, 61, 170);">NodeType</span>] { <span class="" style="color: rgb(187, 44, 162);">get</span> }</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">}</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);">// After</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="color: rgb(187, 44, 162);">protocol</span> Node<T> {</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(187, 44, 162);"><span class="" style=""><span class="Apple-tab-span" style="white-space: pre;">        </span></span>typealias<span class="" style=""> T </span><span class="" style="color: rgb(0, 132, 0);">// probably remove this declaration (see reason below)</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="" style="color: rgb(187, 44, 162);">var</span> value: <span class="" style="color: rgb(112, 61, 170);">T</span> { <span class="" style="color: rgb(187, 44, 162);">get</span> }</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="" style="color: rgb(187, 44, 162);">var</span> nodes: [<span class="" style="color: rgb(112, 61, 170);">Node</span><T>] { <span class="" style="color: rgb(187, 44, 162);">get</span> }</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">}</div></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><br class=""></div><div class=""><div class="" style="margin: 0px; line-height: normal;"><div class="" style="margin: 0px; line-height: normal;"><div class="" style="margin: 0px; line-height: normal;"><div class="" style="margin: 0px; line-height: normal;"><div class="">So a generic parameter is placed after the protocol name. Therefore a corresponding associated type could be synthesized making its declaration in the body of the protocol unnecessary.</div><div class=""><br class=""></div><div class="">In order to let this still compile:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="" style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;">func</span><span class="" style="font-family: Menlo; font-size: 11px;"> afunction<S: </span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">SequenceType</span><span class="" style="font-family: Menlo; font-size: 11px;"> </span><span class="" style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);">where</span><span class="" style="font-family: Menlo; font-size: 11px;"> </span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">S</span><span class="" style="font-family: Menlo; font-size: 11px;">.</span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">Generator</span><span class="" style="font-family: Menlo; font-size: 11px;">.</span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">Element</span><span class="" style="font-family: Menlo; font-size: 11px;"> == </span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">Int</span><span class="" style="font-family: Menlo; font-size: 11px;">>(s: </span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">S</span><span class="" style="font-family: Menlo; font-size: 11px;">){}</span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;"><br class=""></span></div><div class="">there could be a general Swift feature to get the generic type by dot syntax (e.g. synthesized typealiases for every generic parameter).</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Implementation:</div><div class="">The function declaration above could be rewritten to using a function like generic parameter parameter syntax for protocols:</div><div class=""><br class=""></div><div class=""> <span style="color: rgb(0, 132, 0); font-family: Menlo; font-size: 11px;" class="">// Declaration of SequenceType</span></div><div class=""> <span style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;" class="">protocol </span><span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">SequenceType</span><span style="font-family: Menlo; font-size: 11px;" class=""><<font color="#703daa" class="">Element</font>:<font color="#703daa" class=""> Generator.Element</font>,</span> <span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Generator</span><span style="font-family: Menlo; font-size: 11px;" class="">:</span><span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class=""> GeneratorType</span><span style="font-family: Menlo; font-size: 11px;" class="">,</span><span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class=""> </span><span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">SubSequence</span><font face="Menlo" class=""><span style="font-size: 11px;" class="">> { … }</span></font></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class=""> </span></font><span style="color: rgb(0, 132, 0); font-family: Menlo; font-size: 11px;" class="">// ^~~~ using : in oder to allow default types with =</span></div><div class=""><br class=""></div><div class=""> <span style="color: rgb(0, 132, 0); font-family: Menlo; font-size: 11px;" class="">// Using "_" to leave it unspecified eg. Any</span></div><div class=""><span class="" style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;"> func</span><span class="" style="font-family: Menlo; font-size: 11px;"> afunction(s: </span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">SequenceType<Element: Int</span><span class="" style="font-family: Menlo; font-size: 11px;">,</span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;"> Generator: GeneratorType</span><span class="" style="font-family: Menlo; font-size: 11px;"><</span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">Element</span><span class="" style="font-family: Menlo; font-size: 11px;">:</span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;"> Int</span><span class="" style="font-family: Menlo; font-size: 11px;">></span><span class="" style="font-family: Menlo; font-size: 11px;">,</span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;"> SubSequence: _></span><span class="" style="font-family: Menlo; font-size: 11px;">){}</span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;"> </span><span class="" style="color: rgb(0, 132, 0); font-family: Menlo; font-size: 11px;">// omitting `SubSequence: _` since the type is already unambiguous</span></div><div class=""><span class="" style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;"> </span><span class="" style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;">func</span><span class="" style="font-family: Menlo; font-size: 11px;"> afunction(s: </span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">SequenceType</span><span class="" style="font-family: Menlo; font-size: 11px;"><</span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">Element</span><span class="" style="font-family: Menlo; font-size: 11px;">:</span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;"> Int</span><span style="font-family: Menlo; font-size: 11px;" class="">,</span><span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class=""> Generator: </span><span class="" style="font-family: Menlo; font-size: 11px;"><span class="" style="color: rgb(112, 61, 170);">GeneratorType</span><span class=""><</span><span class="" style="color: rgb(112, 61, 170);">Element</span><span class="">:</span><span class="" style="color: rgb(112, 61, 170);"> Int</span><span class="">></span>></span><span class="" style="font-family: Menlo; font-size: 11px;">){}</span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;"><div class="" style="font-family: Helvetica; font-size: 12px;"><span class="" style="font-family: Menlo; font-size: 11px;"> </span><span class="" style="color: rgb(0, 132, 0); font-family: Menlo; font-size: 11px;">// omitting `Generator: GeneratorType<Int>` since the type of `Generator` can be inferred from Element</span></div><div class="" style="font-family: Helvetica; font-size: 12px;"><span class="" style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;"> </span><span class="" style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;">func</span><span class="" style="font-family: Menlo; font-size: 11px;"> afunction(s: </span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">SequenceType</span><span class="" style="font-family: Menlo; font-size: 11px;"><</span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">Element</span><span class="" style="font-family: Menlo; font-size: 11px;">:</span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;"> Int</span><span class="" style="font-family: Menlo; font-size: 11px;">></span><span class="" style="font-family: Menlo; font-size: 11px;">){}</span></div></span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;"><br class=""></span></div><div class="">The order of arguments is in this case irrelevant, but should probably be in a strict ordering to make it more consistent with the point below.</div><div class=""><br class=""></div><div class="">In order to have a more general generic parameter behavior (to work with structs, classes and enums) we could also allow to use these without external names and only their order. So the example above would look like this:</div><div class=""><br class=""></div><div class=""><div class=""><span class="" style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;"> func</span><span class="" style="font-family: Menlo; font-size: 11px;"> afunction(s: </span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">SequenceType<Int</span><span class="" style="font-family: Menlo; font-size: 11px;">,</span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;"> GeneratorType<Int></span><span class="" style="font-family: Menlo; font-size: 11px;">, </span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">_></span><span class="" style="font-family: Menlo; font-size: 11px;">){}</span></div><div class=""><span class="" style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;"> </span><span class="" style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;">func</span><span class="" style="font-family: Menlo; font-size: 11px;"> afunction(s: </span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">SequenceType</span><span class="" style="font-family: Menlo; font-size: 11px;"><</span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">Int</span><span style="font-family: Menlo; font-size: 11px;" class="">, </span><span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">GeneratorType<Int></span><span class="" style="font-family: Menlo; font-size: 11px;">></span><span class="" style="font-family: Menlo; font-size: 11px;">){}</span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;"><div class="" style="font-family: Helvetica; font-size: 12px;"><span class="" style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;"> </span><span class="" style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;">func</span><span class="" style="font-family: Menlo; font-size: 11px;"> afunction(s: </span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">SequenceType</span><span class="" style="font-family: Menlo; font-size: 11px;"><</span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">Int</span><span class="" style="font-family: Menlo; font-size: 11px;">></span><span class="" style="font-family: Menlo; font-size: 11px;">){}</span></div><div class="" style="font-family: Helvetica; font-size: 12px;"><span class="" style="font-family: Menlo; font-size: 11px;"> </span></div><div class="" style="font-family: Helvetica; font-size: 12px;"><span class="" style="font-family: Menlo; font-size: 11px;"> </span><span class="" style="color: rgb(0, 132, 0); font-family: Menlo; font-size: 11px;">// These two functions don't produce an error since `Element` can be inferred</span></div><div class="" style="font-family: Helvetica; font-size: 12px;"><span class="" style="color: rgb(0, 132, 0); font-family: Menlo; font-size: 11px;"> </span><span class="" style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;">func</span><span class="" style="font-family: Menlo; font-size: 11px;"> afunction(s: </span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">SequenceType<</span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">GeneratorType<Int></span><span class="" style="font-family: Menlo; font-size: 11px;">, </span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">_></span><span class="" style="font-family: Menlo; font-size: 11px;">){}</span></div></span><div class=""><span class="" style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;"> </span><span class="" style="color: rgb(187, 44, 162); font-family: Menlo; font-size: 11px;">func</span><span class="" style="font-family: Menlo; font-size: 11px;"> afunction(s: </span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">SequenceType</span><span class="" style="font-family: Menlo; font-size: 11px;"><</span><span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">GeneratorType<Int></span><span class="" style="font-family: Menlo; font-size: 11px;">></span><span class="" style="font-family: Menlo; font-size: 11px;">){}</span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;"><br class=""></span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;"><span style="color: rgb(0, 132, 0);" class=""> // for an unconstrained Sequence "_" can be used in order to make it clear: "there could be generic parameters"</span></span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;"><span class="" style="color: rgb(187, 44, 162);"> </span><span class="" style="color: rgb(187, 44, 162);">func</span><span class=""> afunction(s: </span><span class="" style="color: rgb(112, 61, 170);">SequenceType</span><span class=""><_</span><span class="">></span><span class="">){}</span></span></div></div></div><div class=""><br class=""></div><div class="">For instance `Array` and `Dictionary` also can apply to this model.</div><div class=""><br class=""></div><div class="">Also where clauses could be used in generic parameter declarations which are disallowed for associated types (currently).</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">What do you think about this approach?</div><div class=""><br class=""></div><div class="">Should <span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">SequenceType</span><span class="" style="font-family: Menlo; font-size: 11px;"><_</span><span class="" style="font-family: Menlo; font-size: 11px;">> </span>be <b class="">equal</b> to <span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">SequenceType</span><span class="" style="font-family: Menlo; font-size: 11px;"><</span><span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Any</span><span style="font-family: Menlo; font-size: 11px;" class="">> / </span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">SequenceType</span><span class="" style="font-family: Menlo; font-size: 11px;"><<span style="color: rgb(112, 61, 170);" class="">Element</span>: </span><span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Any</span><span style="font-family: Menlo; font-size: 11px;" class="">></span><span style="font-family: Menlo; font-size: 11px;" class=""> </span>?</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">- Maximilian</div></div></div></div></div></div></div><br class=""><div class=""><blockquote type="cite" class=""><div class="">Am 19.01.2016 um 00:32 schrieb David Waite via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>>:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jan 18, 2016, at 1:18 PM, Douglas Gregor <<a href="mailto:dgregor@apple.com" class="">dgregor@apple.com</a>> 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=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class="">let x:SequenceType = [1,2,3] // no constraints specified whatsoever</div><div class="">let y:protocol<SequenceType where Generator.Element == String> = [“foo”, “bar”] // partially constrained</div></blockquote></div></blockquote><div class=""><br class=""></div>Not wanting to start throwing paint, but "Generator.Element" could be ambiguous with a Generator in the lexical scope. You'll probably want some way to differentiate it (eg, a leading dot). Otherwise, this is the syntactic direction that I think makes the most sense.</div></div></div></blockquote><div class=""><br class=""></div>Yes, I’ll use that below. There is a right balance in extending protocol<>. For instance, I did not like the following at all:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>protocol<S:SequenceType where S.Generator.Element == String></div><div class=""><br class=""></div><div class=""><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=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class="">One interesting side-effect to note is that SequenceType could be redefined to only have “Element” as an associated type. Instead of Generator or SubSequence being associated types, methods could return partially constrained GenericType or SequenceType from the appropriate methods. This would be one way of eliminating issues today with recursive use of associated types (as well as SubSequence over-constraining the output of various algorithms to a single concrete type)</div></div></blockquote><div class=""><br class=""></div><div class="">Assuming nobody cares about the identity of the Generator type, which is probably a safe assumption. Note that one could implement this design today by using a function taking no arguments and returning an Element? in lieu of "Generator”.</div></div></div></div></blockquote><div class=""><br class=""></div>Yes, as an aside I was actually curious GeneratorType existed when I was first diving into the standard library, considering it could just be a closure.</div><div class=""><br class=""><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=""><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class=""></div><div class="">For the “opening” of an existential type to find the concrete type it stores dynamically, I’m currently using a different syntax just because the “open x as T” originally given makes ‘open’ a keyword’ and makes it unclear where ’T’ came from</div></div></blockquote><div class=""><br class=""></div><div class="">Yes, the issue of "which name did I introduce?" is tricky here. </div><br class=""><blockquote type="cite" class=""><div class=""><div class="">- I’m instead overloading the typealias keyword when used within an expression context:</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class="">typealias T = x.dynamicType</div><div class="">let xT = x as! T</div></blockquote></div></blockquote><div class=""><br class=""></div>x will have to be immutable for this to make sense. That's why my ugly "open" expression extracts a new value and gives it a fresh type in one lexically-scoped block. Both the type and the value end up being scoped. Otherwise, one might reassign "x" with a different dynamic type... Then what does T mean?</div></div></div></blockquote><div class=""><br class=""></div><div class="">This is an area that I need to understand compiler behavior more here (I’ve been researching)</div><div class=""><br class=""></div><div class="">If ’T’ internally behaves like an immutable variable with lexical scope, then ’typealias’ in a code block is just another statement, and the type would be based on the value of ‘x’ at the point of execution:</div><div class=""><br class=""></div></div><div class="">var x:Any = “Initial”</div><div class="">typealias T = x.dynamicType // String</div><div class="">x = 1</div><div class="">let xT = x as! T // fails precondition as if I had said x as! String</div><div class=""><br class=""></div><div class="">I’m guessing from your comment however that T would not a variable. In which case, it makes sense to be more restrictive in use (such as requiring immutability). This is also more consistent with the use of typealias in other contexts, if that was the syntax one was going with.</div><div class=""><br class=""></div><div class=""><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="">I suggest you also look at what can be done with an existential value that hasn't been opened explicitly. Can I call "generate" on a SequenceType value, and what do I get back?</div></div></blockquote><div class=""><br class=""></div>Depends on how far we are willing to go. If you are only willing to expose the invariants in the face of the constraints given (in this case none), all you would get exposed is “underestimateCount”.</div><div class=""><br class=""></div><div class="">If you are willing to expose anything which can be expressed by certain type safety rules (needing formal definition later), then you can do quite a bit.</div><div class=""><br class=""></div><div class="">To start, let me express SequenceType relying on the partially constrained protocols, taking a few liberties: </div><div class="">- pruning some alternate forms</div><div class="">- removing SubSequence and Generator associated types and just having Element</div><div class="">- using the protocol<> syntax described before (with . prefix)</div><div class="">- returning partially constrained SequenceTypes rather than stdlib concrete types like JoinSequence in a few cases. </div><div class="">- eliminate usage of AnySequence in definitions (not needed)</div><div class="">- assuming a change in protocol LazySequenceType to be expressed in terms of Element rather than a base SequenceType</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span> SequenceType {</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> associatedtype Element</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span> lazy:<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">LazySequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element == Element> { <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">get</span> }</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> contains(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> predicate:(Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -> Bool) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> dropFirst(n:<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span>) -> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element == Element></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> dropLast(n:<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span>) -> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element == Element></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color: rgb(187, 44, 162);" class="">func</span> elementsEqual(other:<span style="color: rgb(187, 44, 162);" class="">protocol</span><<span style="color: rgb(79, 129, 135);" class="">SequenceType</span> <span style="color: rgb(187, 44, 162);" class="">where</span> .Element == Element>, <span style="color: rgb(187, 44, 162);" class="">@noescape</span> isEquivalent: (Element, Element)) -> Bool</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> enumerate() -> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element == (Int, Element)></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> filter(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> includeElement: (Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span>-> Bool) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -> [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Element</span>]</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> flatMap<E>(transform: (Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><SequenceType <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element:E>) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -> [<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">E</span>]</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> flatMap<T>(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> transform: (Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span>?) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -> [<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span>]</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> forEach(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> body: (Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -> ()) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> generate() -> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">GeneratorType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element == Element></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> lexicographicalCompare(other: <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element == Element>, <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> isOrderedBefore:(Element,Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span>-> Bool) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> map<T>(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> transform: (Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span>) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -> [<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span>]</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> maxElement(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> isOrderedBefore: (Element,Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -> Bool) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Element</span>?</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> minElement(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> isOrderedBefore: (Element,Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -> Bool) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Element</span>?</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> prefix(n:<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span>) -> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element == Element></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> reduce<T>(initial: <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span>, <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> combine: (<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span>, Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span>) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">T</span></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> reverse() -> [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Element</span>]</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> sort(<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> isOrderedBefore: (Element,Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -> Bool) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -> [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Element</span>]</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> split(maxSplit: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span>, allowEmptySubsequences: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span>, <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> isSeparator: (Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -> Bool) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -> [<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element == Element>]</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> startsWith(other: <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element == Element>, <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">@noescape</span> isEquivalent: (Element, Element) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">throws</span> -> Bool) <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">rethrows</span> -> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> suffix(n:<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span>) -> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element == Element></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> underestimateCount() -> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">extension</span> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> Element:Equatable {</div></div><div class=""><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color: rgb(187, 44, 162);" class="">func</span> elementsEqual<OtherSequence : <span style="color: rgb(187, 44, 162);" class="">protocol</span><<span style="color: rgb(79, 129, 135);" class="">SequenceType</span> <span style="color: rgb(187, 44, 162);" class="">where</span> .Element == Element>(other: OtherSequence) -> Bool</div></div><div class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> split(separator: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Element</span>, maxSplit: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Int</span>, allowEmptySlices: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span>) -> [<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element == Element>]</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> startsWith(other: <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element == Element) -> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">extension</span> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> Element == String {</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> joinWithSeparator(separator:<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">String</span>) -> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">String</span></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">extension</span> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> Element:<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><SequenceType></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> flatten() -> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element == Element.Element></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> joinWithSeparator(separator: <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element = Element.Element>) -> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><<span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element == Element.Element>)</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><br class=""></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">extension</span> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> Element:Comparable {</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> lexicographicalCompare(other: <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span><<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">SequenceType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> .Element == Element>) -> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Bool</span></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> maxElement() -> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Element</span>?</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> minElement() -> <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Element</span>?</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> sort() -> [<span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">Element</span>]</div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div></blockquote>Now, mapping this in terms of just an unconstrained SequenceType, which is shorthand for protocol<SequenceType where .Element:Any>:<div class="">- None of the extensions match the constraint on Element, so they are not exposed</div><div class="">- property Lazy is exposed as an unconstrained LazySequenceType, aka protocol<LazySequenceType where .Element:Any></div><div class="">- the predicate function in contains is not constrained by a particular kind of element, so it becomes (Any)->Bool, e.g.:</div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);" class="">func</span><span style="font-family: Menlo; font-size: 11px;" class=""> contains(</span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);" class="">@noescape</span><span style="font-family: Menlo; font-size: 11px;" class=""> predicate:(Any) </span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);" class="">throws</span><span style="font-family: Menlo; font-size: 11px;" class=""> -> Bool) </span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);" class="">rethrows</span><span style="font-family: Menlo; font-size: 11px;" class=""> -> </span><span style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);" class="">Bool</span></div></blockquote><div class=""><div class="">- dropFirst/dropLast would return an unconstrained SequenceType. This would need to leverage rules around constrained protocol variance/equivalence.</div><div class="">- elementsEqual was changed to no longer be generic - one can pass in any SequenceType constrained to have the same Element type. The function parameter, similar to contains above, now has the signature (Any, Any)->Bool</div><div class="">- enumerate() will return a sequence with elements of type (Int, Any)</div><div class="">- filter takes a (Any) throws -> Bool method and returns [Any]</div><div class="">- flatMap and forEach are exposed similar to contains above</div><div class="">- generate returns an unconstrained GeneratorType (so it will have a single method func next() -> Any?)</div><div class="">- lexicographicalCompare fails, more below</div><div class="">- reduce has effective syntax:</div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class=""> <span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);" class="">func</span><span style="font-family: Menlo; font-size: 11px;" class=""> reduce<T>(initial: </span><span style="font-family: Menlo; font-size: 11px; color: rgb(79, 129, 135);" class="">T</span><span style="font-family: Menlo; font-size: 11px;" class="">, </span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);" class="">@noescape</span><span style="font-family: Menlo; font-size: 11px;" class=""> combine: (</span><span style="font-family: Menlo; font-size: 11px; color: rgb(79, 129, 135);" class="">T</span><span style="font-family: Menlo; font-size: 11px;" class="">, Any) </span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);" class="">throws</span><span style="font-family: Menlo; font-size: 11px;" class=""> -> </span><span style="font-family: Menlo; font-size: 11px; color: rgb(79, 129, 135);" class="">T</span><span style="font-family: Menlo; font-size: 11px;" class="">) </span><span style="font-family: Menlo; font-size: 11px; color: rgb(187, 44, 162);" class="">rethrows</span><span style="font-family: Menlo; font-size: 11px;" class=""> -> </span><span style="font-family: Menlo; font-size: 11px; color: rgb(79, 129, 135);" class="">T</span></div></div></blockquote><div class="">- the rest are exposed as above except for startsWith</div><div class=""><br class=""></div><div class="">So all functionality except<span style="font-family: Menlo; font-size: 11px;" class=""> lexicographicalCompare and </span><span style="font-family: Menlo; font-size: 11px;" class="">startsWith </span>could at least in theory be exposed safely. These cannot be exposed cleanly because method expected an input sequence with the same element type, but the element type is not invariantly constrained. Self properties and method arguments are an equivalent problem, except that for a Self argument can only be invariantly constrained when you know the implementing concrete type - hence wanting a system to dynamically reason about said types.</div><div class=""><br class=""></div><div class="">This seems like a good amount of exposed functionality. Granted, it is not free to work at the level of protocols vs concrete types, and this does not attempt to simplify that. However, this proposal seems to bridge the gap between protocols without associated types and protocols with them. I also am happy with the amount of functionality that can be exposed safely as well as the consistency (A lexicographicalCompare function working on heterogenous sequences would have to be declared differently)</div><div class=""><br class=""></div><div class="">-DW</div><div class=""><br class=""></div><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""><div class=""></div></blockquote><div class=""><blockquote style="margin: 0px 0px 0px 40px; border: none; padding: 0px;" class=""></blockquote></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div></blockquote></body></html>