<div dir="ltr">I&#39;ve been using generics a fair amount recently. The Swift 3 notes declare an intention for &#39;complete generics&#39;, but there isn&#39;t much information on what this consists of.<div><br></div><div>I think there are three key elements to the terminology here. In a declaration of a generic type, you have associated types, generic parameters, and generic constraints. I imagine the Swift for a Set type looks like this:</div><div><br></div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span><span style="color:rgb(187,44,162)">struct</span> Set&lt;Element <span style="color:rgb(187,44,162)">where</span> Element : Hashable&gt; : <span style="color:rgb(112,61,170)">CollectionType</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span>{</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)"><span style="color:rgb(0,0,0)"><span style="white-space:pre-wrap">                </span></span><span style="color:rgb(187,44,162)">typealias</span><span style="color:rgb(0,0,0)"> Index = </span>SetIndex<span style="color:rgb(0,0,0)">&lt;</span>Element<span style="color:rgb(0,0,0)">&gt;</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span>}</p></div><div><br></div><div><br></div><div>Element is a generic parameter. Element : Hashable is a generic constraint. Index is an associated type and it&#39;s required to conform to CollectionType. The distinction is important; we could create a non-generic type IntSet like this:</div><div><br></div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)"><span style="color:rgb(0,0,0)"><span style="white-space:pre-wrap">        </span></span><span style="color:rgb(187,44,162)">struct</span><span style="color:rgb(0,0,0)"> IntSet : </span>CollectionType</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span>{</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:rgb(187,44,162)">typealias</span> Index = <span style="color:rgb(112,61,170)">SetIndex</span>&lt;<span style="color:rgb(112,61,170)">Int</span>&gt;</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span>}</p></div><div><br></div><div>I think it should be possible to declare a property which conforms to CollectionType, constrained such that its Index is a SetIndex&lt;Int&gt; type (as opposed to, say, SetIndex&lt;String&gt;). Or, I think it should be possible to declare a property which conforms to GeneratorType, constrained that its Element conforms to IntegerArithmeticType, so I can generate random numbers and add them together and not yet decide whether they&#39;re Ints or Doubles or whether the generation was by dice or playing cards.</div><div><br></div><div>I think I should be able to declare a Graph generic data structure with values for its nodes and edges - e.g. a Travelling Salesman Problem graph of Graph&lt;City, Route&gt; - and have a matching generic GraphTraverser type which takes a graph and a starting node, and traverses the graph reporting to a matching GraphTraversalDelegate type when it traverses an edge, reaches a node, or needs a decision making on which of the available edges it should traverse next. For this, the GraphTraverser should have a matching &#39;generic parameter signature&#39; to the Graph, but the GraphTraversalDelegate will be context specific and should dictate type-safe decisions based on City nodes and Route edges.</div><div><br></div><div>At the moment, this traversal pattern isn&#39;t possible because protocols can&#39;t have generic parameters. I&#39;ve seen programmers develop &#39;thunk&#39; types to work around this, but this should be neater.</div><div><br></div><div>So, I think it&#39;s important that we keep generic parameters and associated types distinct - but, protocols should be able to handle generics, perhaps with some implicit typealiasing.</div><div><br></div><div>The OP&#39;s examples; the developer would write this:</div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span><span style="color:rgb(187,44,162)">protocol</span> FooType&lt;Element, Index <span style="color:rgb(187,44,162)">where</span> Index : ForwardIndexType&gt; {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:rgb(187,44,162)">func</span> getElement(atIndex:<span style="color:rgb(112,61,170)">Index</span>) -&gt; <span style="color:rgb(112,61,170)">Element</span>?</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span>}</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span><span style="color:rgb(187,44,162)">struct</span> Foo&lt;Element&gt; : <span style="color:rgb(79,129,135)">FooType</span>&lt;<span style="color:rgb(112,61,170)">Element</span>, <span style="color:rgb(112,61,170)">Int</span>&gt; {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:rgb(187,44,162)">func</span> getElement(atIndex:<span style="color:rgb(112,61,170)">Index</span>) -&gt; <span style="color:rgb(112,61,170)">Element</span>? { <font color="#bb2ca2">...</font> }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">





</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span>}</p><div><br></div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">
</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap"><span style="font-family:arial,sans-serif;font-size:small;white-space:normal">But what would result would be this:</span><br></span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span><span style="color:rgb(187,44,162)">protocol</span> FooType&lt;Element, Index <span style="color:rgb(187,44,162)">where</span> Index : ForwardIndexType&gt; {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)"><span style="white-space:pre-wrap">                </span></span><span style="color:rgb(187,44,162)">typealias</span><span style="color:rgb(0,0,0)"> Element </span>// implicitly generated associatedtypes and typealiases</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)"><span style="white-space:pre-wrap">                </span></span><span style="color:rgb(187,44,162)">typealias</span><span style="color:rgb(0,0,0)"> Index </span>// implicit</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:rgb(187,44,162)">func</span> getElement(atIndex:<span style="color:rgb(112,61,170)">Index</span>) -&gt; <span style="color:rgb(112,61,170)">Element</span>?</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span>}</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span><span style="color:rgb(187,44,162)">struct</span> Foo&lt;Element&gt; : <span style="color:rgb(79,129,135)">FooType</span> {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)"><span style="white-space:pre-wrap">                </span></span><span style="color:rgb(187,44,162)">typealias</span><span style="color:rgb(0,0,0)"> Element = </span><span style="color:rgb(112,61,170)">Element</span><span style="color:rgb(0,0,0)"> </span>// implicitly generated associatedtypes and typealiases</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:rgb(187,44,162)">typealias</span> Index = <span style="color:rgb(112,61,170)">Int</span> <span style="color:rgb(0,132,0)">// implicit</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:rgb(187,44,162)">func</span> getElement(atIndex:<span style="color:rgb(79,129,135)">Index</span>) -&gt; <span style="color:rgb(112,61,170)">Element</span>? { <span style="color:rgb(187,44,162)">return</span> <span style="color:rgb(187,44,162)">nil</span> }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">










</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span>}</p></div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><br></p></div><div>I&#39;m not sure what I&#39;d prefer for the syntax of a type which e.g. conformed to FooType and whose Index was an Int. One of these two?</div><div>1) generic parameters matched by position in sequence</div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span><span style="color:rgb(187,44,162)">let</span> foo : FooType&lt;<span style="color:rgb(187,44,162)">_</span>, Int&gt; = Foo&lt;<span style="color:rgb(112,61,170)">String</span>&gt;</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap"><span style="font-family:arial,sans-serif;font-size:small">2) associated type matched to type.</span></span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span><span style="color:rgb(187,44,162)">let</span> foo : FooType&lt;<font color="#bb2ca2">Index:</font>Int&gt; = Foo&lt;<span style="color:rgb(112,61,170)">String</span>&gt;</p></div><div><br></div><div>Here&#39;s a further code example - the graph traverser from before might look like this:</div><div><br></div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span><span style="color:rgb(187,44,162)">struct</span> GraphTraverser&lt;NodeType, EdgeType&gt;</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span>{</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)"><span style="color:rgb(0,0,0)"><span style="white-space:pre-wrap">                </span></span><span style="color:rgb(187,44,162)">let</span><span style="color:rgb(0,0,0)"> graph : </span>Graph<span style="color:rgb(0,0,0)">&lt;</span>NodeType<span style="color:rgb(0,0,0)">, </span>EdgeType<span style="color:rgb(0,0,0)">&gt;</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:rgb(187,44,162)">var</span> currentNode : <span style="color:rgb(112,61,170)">NodeType</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(79,129,135)"><span style="color:rgb(0,0,0)"><span style="white-space:pre-wrap">                </span></span><span style="color:rgb(187,44,162)">weak</span><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(187,44,162)">var</span><span style="color:rgb(0,0,0)"> delegate : </span>GraphTraversalDelegate<span style="color:rgb(0,0,0)">&lt;</span><span style="color:rgb(112,61,170)">NodeType</span><span style="color:rgb(0,0,0)">, </span><span style="color:rgb(112,61,170)">EdgeType</span><span style="color:rgb(0,0,0)">&gt;?</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:rgb(187,44,162)">func</span> move()</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span>{</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                        </span><span style="color:rgb(187,44,162)">let</span> options = graph.edgesFromNode(currentNode)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                        </span><span style="color:rgb(187,44,162)">if</span> <span style="color:rgb(187,44,162)">let</span> decision = delegate?.graphTraverser(<span style="color:rgb(187,44,162)">self</span>, chooseEdgeFromOptions:options)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                        </span>{</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                                </span>currentNode = decision.destination</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                                </span>delegate?.graphTraverser(<span style="color:rgb(187,44,162)">self</span>, didTraverseEdge:decision)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                                </span><span style="color:rgb(79,129,135)">delegate</span>?.graphTraverser(<span style="color:rgb(187,44,162)">self</span>, didReachNode:currentNode)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                        </span>}</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span>}</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span>}</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span><span style="color:rgb(187,44,162)">protocol</span> GraphTraversalDelegate&lt;NodeType, EdgeType&gt;</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span>{</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)"><span style="white-space:pre-wrap">                </span></span>// implicit typealiasing</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:rgb(187,44,162)">func</span> graphTraverser(graphTraverser:<span style="color:rgb(112,61,170)">GraphTraverser</span>&lt;<span style="color:rgb(112,61,170)">NodeType</span>, <span style="color:rgb(112,61,170)">EdgeType</span>&gt;, didTraverseEdge edge:<span style="color:rgb(112,61,170)">EdgeType</span>)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:rgb(187,44,162)">func</span> graphTraverser(graphTraverser:<span style="color:rgb(112,61,170)">GraphTraverser</span>&lt;<span style="color:rgb(112,61,170)">NodeType</span>, <span style="color:rgb(112,61,170)">EdgeType</span>&gt;, didReachNode node:<span style="color:rgb(112,61,170)">NodeType</span>)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:rgb(187,44,162)">func</span> graphTraverser(graphTraverser:<span style="color:rgb(112,61,170)">GraphTraverser</span>&lt;<span style="color:rgb(112,61,170)">NodeType</span>, <span style="color:rgb(112,61,170)">EdgeType</span>&gt;, chooseEdgeFromOptions options:[<span style="color:rgb(112,61,170)">EdgeType</span>]) -&gt; <span style="color:rgb(112,61,170)">EdgeType</span>?</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span>}</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span><span style="color:rgb(187,44,162)">struct</span> TravellingSalesman : <span style="color:rgb(79,129,135)">GraphTraversalDelegate</span>&lt;<span style="color:rgb(112,61,170)">City</span>, <span style="color:rgb(112,61,170)">Route</span>&gt;</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span>{</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span style="color:rgb(0,0,0)"><span style="white-space:pre-wrap">                </span></span>// implicit typealiasing; all NodeTypes are City, all EdgeType are Route</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:rgb(187,44,162)">var</span> citiesVisited : <span style="color:rgb(112,61,170)">Set</span>&lt;<span style="color:rgb(112,61,170)">City</span>&gt;</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:rgb(187,44,162)">var</span> distanceTravelled : <span style="color:rgb(112,61,170)">Int</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p>
<p style="margin:0px;line-height:normal"><span style="font-family:Menlo;font-size:11px;white-space:pre-wrap">                </span><font color="#bb2ca2" face="Menlo"><span style="font-size:11px">mutating</span></font><span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)"> func</span><font face="Menlo"><span style="font-size:11px"> graphTraverser(graphTraverser:</span></font><span style="font-family:Menlo;font-size:11px;color:rgb(112,61,170)">GraphTraverser</span><font face="Menlo"><span style="font-size:11px">&lt;</span></font><span style="font-family:Menlo;font-size:11px;color:rgb(112,61,170)">City</span><font face="Menlo"><span style="font-size:11px">, </span></font><span style="font-family:Menlo;font-size:11px;color:rgb(112,61,170)">Route</span><font face="Menlo"><span style="font-size:11px">&gt;, didTraverseEdge edge:</span></font><span style="font-family:Menlo;font-size:11px;color:rgb(112,61,170)">Route</span><font face="Menlo"><span style="font-size:11px">)</span></font></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span>{</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                        </span>distanceTravelled += edge.distance</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span>}</p>
<p style="margin:0px;line-height:normal"><span style="font-family:Menlo;font-size:11px;white-space:pre-wrap">                </span><font color="#bb2ca2" face="Menlo"><span style="font-size:11px">mutating</span></font><span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)"> func</span><font face="Menlo"><span style="font-size:11px"> graphTraverser(graphTraverser:</span></font><span style="font-family:Menlo;font-size:11px;color:rgb(112,61,170)">GraphTraverser</span><font face="Menlo"><span style="font-size:11px">&lt;</span></font><span style="font-family:Menlo;font-size:11px;color:rgb(112,61,170)">City</span><font face="Menlo"><span style="font-size:11px">, </span></font><span style="font-family:Menlo;font-size:11px;color:rgb(112,61,170)">Route</span><font face="Menlo"><span style="font-size:11px">&gt;, didReachNode node:</span></font><span style="font-family:Menlo;font-size:11px;color:rgb(112,61,170)">City</span><font face="Menlo"><span style="font-size:11px">)</span></font></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span>{</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                        </span>citiesVisited.insert(node)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                        </span>graphTraverser.move()</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span>}</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span><span style="color:rgb(187,44,162)">func</span> graphTraverser(graphTraverser:<span style="color:rgb(112,61,170)">GraphTraverser</span>&lt;<span style="color:rgb(112,61,170)">City</span>, <span style="color:rgb(112,61,170)">Route</span>&gt;, chooseEdgeFromOptions options:[<span style="color:rgb(112,61,170)">Route</span>]) -&gt; <span style="color:rgb(112,61,170)">Route</span>?</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span>{</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                        </span><span style="color:rgb(187,44,162)">return</span> Random(options.filter{ route in !citiesVisited.contains(route.destination) })</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">                </span>}</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span>}</p></div><div><br></div><div>Comments?</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Feb 26, 2016 at 11:22 AM, Haravikk via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">One of the big things that bugs me about working with protocols and generics is that they have a fundamentally different style to working with generics on structs and classes. While has some minor benefits on differentiating them, I think that overall it results in inconsistency that makes them harder to work with.<div><br></div><div>I’d like to propose two fairly minor changes that allow protocols to be defined using angle brackets for generics to make things much easier. </div><div><br></div><div>First is allowing a protocol to be defined using angle brackets for its generic type(s) like so:</div><div><br></div><div><font face="Monaco"><span style="white-space:pre-wrap">        </span>protocol FooType&lt;Element, Index:ForwardIndexType&gt; {</font></div><div><font face="Monaco"><span style="white-space:pre-wrap">                </span>func getElement(atIndex:Index) -&gt; Element?</font></div><div><font face="Monaco"><span style="white-space:pre-wrap">        </span>}</font></div><div><br></div><div>In this example the protocol Foo has implicit type aliases for Element and Index, which can be fulfilled like so:</div><div><br></div><div><font face="Monaco"><span style="white-space:pre-wrap">        </span>struct Foo&lt;Element&gt; : FooType&lt;Element, Int&gt; {</font></div><div><font face="Monaco"><span style="white-space:pre-wrap">                </span>func getElement(atIndex:Index) -&gt; Element? { … }</font></div><div><font face="Monaco"><span style="white-space:pre-wrap">        </span>}</font></div><div><br></div><div>The other important case is defining type constraints with protocol generics, currently we have to do stuff like this:</div><div><br></div><div><font face="Monaco"><span style="white-space:pre-wrap">        </span>func append&lt;S:SequenceType where S.Generator.Element == Element&gt;(contentsOf theSequence:S) { … }</font></div><div><br></div><div>However, while definition with a where clause is powerful, in the majority of cases it’s much more complex than it needs to be. So I’d like to propose that we can have the following:</div><div><br></div><div><font face="Monaco"><span style="white-space:pre-wrap">        </span>protocol SequenceType&lt;Element&gt; { … }</font></div><div><font face="Monaco"><span style="white-space:pre-wrap">        </span>func append(contentsOf theSequence:SequenceType&lt;Element&gt;) { … }</font></div><div><br></div><div>Behind the scenes these may be unwrapped into type aliases and where clauses like we have now, but for the developers this is much, much simpler to work with, especially when most generic constraints are pretty simple.</div><div><br></div><div>I’m not proposing the removal of where clauses as they can be really useful in more unusual cases, so will still have utility there. I’m not so sure about explicit type alias declaration like we have now though; using the angle brackets to declare these seems just as capable to me unless there are some cases I haven’t considered.</div><div><br></div><div><br></div><div>This seems like something that may have been discussed in the past, but I’m not that great on specific terminology for features (I’m not as well versed as others are on the correct names for language features) so I haven’t found anything, but fully expect that I may have missed it somehow, in which case a link would be appreciated.</div><div><br></div><div>But if no proposal currently exists then I’d love to know, as I could try to create a more formal proposal for this if necessary, as I know that I for one would benefit greatly from simplified protocol generics, as they’re currently one of my least favourite features to use syntactically, but one I need to use a lot.</div></div><br>_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br></blockquote></div><br></div>