<div dir="ltr">Would the optimisation I suggested in previous email address your concern of needing both associated types and generics in protocols?<div><br></div><div> -- Howard.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On 13 January 2016 at 08:31, Austin Zheng via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">AFAIK traits in Rust can have both associated types and generic type parameters. I think a corresponding feature for Swift would be a net positive, albeit I haven't examined the tradeoffs and advantages in any detail yet.<div><br></div><div>Austin</div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jan 12, 2016 at 1:16 PM, Maximilian Hünenberger <span dir="ltr"><<a href="mailto:m.huenenberger@me.com" target="_blank">m.huenenberger@me.com</a>></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"><div>1+ for adding generics to protocols.</div><div><br></div><div>What about generics in protocols which are only a view to its associated types or generics which create/are associated types?</div><div><br></div><div>Example of a simple protocol which models a node of a tree:</div><div><br></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">// Before</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">// NodeType can be anything</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">// currently Swift doesn't allow</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">// `typealias NodeType: Node`</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">//</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">// or even where clauses </div><div 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 style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(187,44,162)">protocol<span style="color:#000000"> Node {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(187,44,162)"><span style="color:#000000"><span style="white-space:pre-wrap">        </span></span>typealias<span style="color:#000000"> T</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span><span style="color:#bb2ca2">typealias</span> NodeType</div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span style="white-space:pre-wrap">        </span><br></p><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span><span style="color:#bb2ca2">var</span> value: <span style="color:#703daa">T</span> { <span style="color:#bb2ca2">get</span> }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span><span style="color:#bb2ca2">var</span> nodes: [<span style="color:#703daa">NodeType</span>] { <span style="color:#bb2ca2">get</span> }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)">// After</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">protocol</span> Node<T> {</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(187,44,162)"><span style="color:#000000"><span style="white-space:pre-wrap">        </span></span>typealias<span style="color:#000000"> T </span><span style="color:rgb(0,132,0)">// probably remove this declaration</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span><span style="color:#bb2ca2">var</span> value: <span style="color:#703daa">T</span> { <span style="color:#bb2ca2">get</span> }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="white-space:pre-wrap">        </span><span style="color:#bb2ca2">var</span> nodes: [<span style="color:#703daa">Node</span><T>] { <span style="color:#bb2ca2">get</span> }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">}</div></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><br></div><div><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><div style="margin:0px;line-height:normal"><div>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><br></div><div>In order to let</div><div><br></div><div><span style="white-space:pre-wrap">        </span><span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">func</span><span style="font-family:Menlo;font-size:11px"> afunction<S: </span><span style="color:rgb(112,61,170);font-family:Menlo;font-size:11px">SequenceType</span><span style="font-family:Menlo;font-size:11px"> </span><span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)">where</span><span style="font-family:Menlo;font-size:11px"> </span><span style="color:rgb(112,61,170);font-family:Menlo;font-size:11px">S</span><span style="font-family:Menlo;font-size:11px">.</span><span style="color:rgb(112,61,170);font-family:Menlo;font-size:11px">Generator</span><span style="font-family:Menlo;font-size:11px">.</span><span style="color:rgb(112,61,170);font-family:Menlo;font-size:11px">Element</span><span style="font-family:Menlo;font-size:11px"> == </span><span style="color:rgb(112,61,170);font-family:Menlo;font-size:11px">Int</span><span style="font-family:Menlo;font-size:11px">>(s: </span><span style="color:rgb(112,61,170);font-family:Menlo;font-size:11px">S</span><span style="font-family:Menlo;font-size:11px">){}</span></div><div><span style="font-family:Menlo;font-size:11px"><br></span></div><div>still compile 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><br></div><div>The function declaration above could be rewritten to using function like parameter syntax:</div><div><br></div><div><span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px"> func</span><span style="font-family:Menlo;font-size:11px"> afunction(s: </span><span style="color:rgb(112,61,170);font-family:Menlo;font-size:11px">SequenceType<Generator: GeneratorType<Int>, SubSequence: _></span><span style="font-family:Menlo;font-size:11px">){}</span></div><div><span style="font-family:Menlo;font-size:11px"> </span><span style="color:rgb(0,132,0);font-family:Menlo;font-size:11px">// or omitting `SubSequence: _` since the type is already unambiguous</span></div><div><span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px"> func</span><span style="font-family:Menlo;font-size:11px"> afunction(s: </span><span style="color:rgb(112,61,170);font-family:Menlo;font-size:11px">SequenceType<Generator: GeneratorType<Int>></span><span style="font-family:Menlo;font-size:11px">){}</span></div><div><span style="font-family:Menlo;font-size:11px"><br></span></div><div>in this case there is almost no win. But as you can see in the example with the protocol, generics allow for much better abstraction.</div><div><br></div><div>Also where clauses could be used in generic parameter declarations which are disallowed for associated types.</div><span><font color="#888888"><div><br></div><div><br></div><div>Maximilian</div></font></span></div></div></div><div style="font-family:Menlo;font-size:11px;color:rgb(187,44,162);margin:0px;line-height:normal"><br></div></div></div><div><div><div><blockquote type="cite"><div>Am 12.01.2016 um 19:19 schrieb Jordan Rose via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>>:</div><br><div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Agreed on both counts. Generics are more familiar but don't actually cover the use cases where the associated type is<span> </span><i>not</i> independent of the model object (like a Sequence's Generator or a Collection's Index). Dropping that information results in a lot of extra indirection at runtime, which we don't want.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Jordan</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br><div><blockquote type="cite"><div>On Jan 12, 2016, at 8:17, Austin Zheng via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br><div><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">Strong -1, covariance on generics should be explicitly opt-in. Also -1 on generics replacing associated types in protocols.</span><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Austin</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br><div><blockquote type="cite"><div>On Jan 12, 2016, at 1:45 AM, Howard Lovatt via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br><div><div style="word-wrap:break-word"><div style="margin:0px;line-height:normal"><font face="Menlo"><span style="font-size:11px">Currently you generics are invariant whereas function arguments etc. are covariant. I am suggesting that if the way generics are implemented is changed then they can be made covariant and that this will add considerable utility to Swift generics.</span></font></div><div style="margin:0px;line-height:normal"><font face="Menlo"><span style="font-size:11px"><br></span></font></div><div style="margin:0px;line-height:normal"><font face="Menlo"><span style="font-size:11px">1st a demonstration of the current situation of invariant generics:</span></font></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span><br></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> </span>// Current system</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(187,44,162)">class</span><span> </span>Top {}</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(187,44,162)">class</span><span> </span>Bottom:<span> </span><span style="color:rgb(79,129,135)">Top</span><span> </span>{}</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(187,44,162)">struct</span><span> </span>Box<T: AnyObject> {</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(187,44,162)">var</span><span> </span>value:<span> </span><span style="color:rgb(112,61,170)">T</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(187,44,162)">init</span>(<span style="color:rgb(187,44,162)">_</span><span> </span>initialValue:<span> </span><span style="color:rgb(112,61,170)">T</span>) {</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(79,129,135)">value</span><span> </span>= initialValue;</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(187,44,162)">let</span><span> </span>boxB =<span> </span><span style="color:rgb(79,129,135)">Box</span>(<span style="color:rgb(79,129,135)">Bottom</span>())</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// let boxT: Box<Top> = boxB // Covariance currently not allowed</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">The key point is although `Bottom` 'is a’ `Top`, `Box<Bottom>` *is not* a `Box<Top>`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">I am suggesting:</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">1. That `Box<Bottom>` should be a `Box<Top>` (covariance).</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">2. An implementation that allows the above covariance.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">3. That protocols are made generic, i.e. `protocol Box<T> { var value: T { get set } }` and that this mechanism replaces associated types for protocols.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// Proposal:</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// 1. No change to Box, i.e. programmer would just write Box as before</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// 2. Code transformed by comiler with write check for each specific, generic type instance</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// Best approximation of resulting code in current Swift to demonstrate spirit of idea:</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// Compiler writes a universal form using the upper bound (it writes the underlyting representation).</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// In practice this would be called `Box` but used `BoxAnyObject` to indicate that it has a generic argument bounded by `AnyObject`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(187,44,162)">struct</span><span> </span>BoxAnyObject {</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// Generated from generic argument `<T: AnyObject>`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span><span style="color:rgb(187,44,162)">let</span><span><span> </span>T:<span> </span></span><span style="color:rgb(112,61,170)">AnyObject</span><span>.Type<span> </span></span>// Store the actual type.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"> <br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// Generated from stored property `var value: T` and noting that `T`'s upper bound is `AnyObject`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span><span style="color:rgb(187,44,162)">private</span><span><span> </span></span><span style="color:rgb(187,44,162)">var</span><span><span> </span>_value:<span> </span></span><span style="color:rgb(112,61,170)">AnyObject</span><span><span> </span></span>// Access the stored property through a setter so that type can be checked</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(187,44,162)">var</span><span> </span>value:<span> </span><span style="color:rgb(112,61,170)">AnyObject</span><span> </span>{</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(187,44,162)">get</span><span> </span>{</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(187,44,162)">return</span><span> </span><span style="color:rgb(79,129,135)">_value</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(187,44,162)">set</span><span> </span>{</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// In all functions check that args declared as `T` are actually a `T` or a sub-type.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// Note: `is` only works with type literal and there is no `>=` operator for types :(.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// `is` would need changing or `>=` for types adding, nearest at moment `==`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(209,47,27)"><span> <span> </span></span><span style="color:rgb(61,29,129)">precondition</span><span>(</span><span style="color:rgb(79,129,135)">T</span><span><span> </span>==<span> </span></span><span style="color:rgb(0,132,0)">/* >= */</span><span><span> </span>newValue.</span><span style="color:rgb(187,44,162)">dynamicType</span><span>,<span> </span></span>"Type of newValue,<span> </span><span>\</span>(<span>newValue.</span><span style="color:rgb(187,44,162)">dynamicType</span>), is not a sub-type of generic type T,<span> </span><span>\</span>(<span style="color:rgb(79,129,135)">T</span>)"<span>)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(79,129,135)">_value</span><span> </span>= newValue</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"> <br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// Generated from `init(_ initialValue: T)` and noting that `T`'s upper bound is `AnyObject`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(187,44,162)">init</span>(<span style="color:rgb(187,44,162)">_</span><span> </span>lowestCommonDeclaredT:<span> </span><span style="color:rgb(112,61,170)">AnyObject</span>.Type,<span> </span><span style="color:rgb(187,44,162)">_</span><span> </span>initialValue:<span> </span><span style="color:rgb(112,61,170)">AnyObject</span>) {</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(79,129,135)">T</span><span> </span>= lowestCommonDeclaredT</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(79,129,135)">_value</span><span> </span>= initialValue</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// Demonstrate that all `Box`es are the same size and therefore can be bitwise copied</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// Compiler supplies lowest-common, declared, generic type for all the `T`s in the `init` call.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span><span style="color:rgb(187,44,162)">var</span><span><span> </span>bT =<span> </span></span><span style="color:rgb(79,129,135)">BoxAnyObject</span><span>(</span><span style="color:rgb(79,129,135)">Top</span><span>.</span><span style="color:rgb(187,44,162)">self</span><span>,<span> </span></span><span style="color:rgb(79,129,135)">Top</span><span>())<span> </span></span>// In practice user would write `let bT = Box(Top())`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span><span style="color:rgb(79,129,135)">bT</span><span>.</span><span style="color:rgb(79,129,135)">T</span><span><span> </span></span>// Top.Type</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(61,29,129)"><span> <span> </span></span>sizeofValue<span>(</span><span style="color:rgb(79,129,135)">bT</span><span>)<span> </span></span><span style="color:rgb(0,132,0)">// 16</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span><span style="color:rgb(187,44,162)">var</span><span><span> </span>bB =<span> </span></span><span style="color:rgb(79,129,135)">BoxAnyObject</span><span>(</span><span style="color:rgb(79,129,135)">Bottom</span><span>.</span><span style="color:rgb(187,44,162)">self</span><span>,<span> </span></span><span style="color:rgb(79,129,135)">Bottom</span><span>())<span> </span></span>// In practice user would write `let bB = Box(Bottom())`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span><span style="color:rgb(79,129,135)">bB</span><span>.</span><span style="color:rgb(79,129,135)">T</span><span><span> </span></span>// Bottom.Type</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(61,29,129)"><span> <span> </span></span>sizeofValue<span>(</span><span style="color:rgb(79,129,135)">bB</span><span>)<span> </span></span><span style="color:rgb(0,132,0)">// 16</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// Demonstration covariance.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span><span style="color:rgb(79,129,135)">bT</span><span><span> </span>=<span> </span></span><span style="color:rgb(79,129,135)">bB</span><span><span> </span></span>// Compiler would check covariance of declared generic types.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span><span style="color:rgb(79,129,135)">bT</span><span>.</span><span style="color:rgb(79,129,135)">T</span><span><span> </span></span>// Bottom.Type</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// Demonstrate generic returned type</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// Compiler would add cast to declared, generic type.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span><span style="color:rgb(79,129,135)">bB</span><span>.</span><span style="color:rgb(79,129,135)">value</span><span><span> </span></span><span style="color:rgb(187,44,162)">as</span><span>!<span> </span></span><span style="color:rgb(79,129,135)">Bottom</span><span><span> </span></span>// In practice user would write `bB.value`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// Demonstrate type safety</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span><span style="color:rgb(79,129,135)">bT</span><span><span> </span>=<span> </span></span><span style="color:rgb(79,129,135)">BoxAnyObject</span><span>(</span><span style="color:rgb(79,129,135)">Top</span><span>.</span><span style="color:rgb(187,44,162)">self</span><span>,<span> </span></span><span style="color:rgb(79,129,135)">Top</span><span>())<span> </span></span>// In practice user would write `bT = Box(Top())`.</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span> </span><span style="color:rgb(79,129,135)">bT</span>.<span style="color:rgb(79,129,135)">value</span><span> </span>=<span> </span><span style="color:rgb(79,129,135)">Top</span>()<span> </span><span style="color:rgb(0,132,0)">// OK</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// bT.value = Bottom() // Doesn't work at present because need `>=` for types, but would work in practice</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(0,132,0)"><span> <span> </span></span>// bB.value = Top() // Runtime error - wrong type</div><div><br></div><div>The implications of this proposal are:</div><div><br></div><div>1. The compiler can statically type check a read from a stored property.</div><div>2. A write to a stored property is type checked at runtime.</div><div>3. Protocols can be made generic instead of having an associated type and then they become a proper type with dynamic dispatch.</div><div>4. Generic protocols can be a type just like non-generic protocols, structs, and classes and unlike associated type protocols that can only be a generic constraint.</div><div>5. The awkwardness of dealing with associated type generics is replaced by a more powerful and easier to understand semantic of a type, just like the other types.</div><div>6. There is a lot of ‘non-obvoius’, long code, for example `inits`, that use a `where` clause to constrain an associated type protocol, this would be unnecessary.</div><div>7. There are whole types, `AnySequence`, `AnyGenerator`, etc., that would be replaced by a generic protocols, `Sequence`, `Generator`, etc.</div><div><br></div><div>Advantages:</div><div><br></div><div>1. Covariant generics are a powerful addition to the language.</div><div>2. Generics’ invariance are inconsistent with the rest of the language.</div><div>3. Generic protocols would become a ‘proper’ type and you could have arrays and fields of a generic protocol.</div><div>4. There are many threads on swift-evolution looking at how protocols can be made into a ‘proper’ type or at least a concept that is easier to understand.</div><div><br></div><div>Compatibility:</div><div><br></div><div>1. This would be a major change since associated types in protocols would be replaced by generics.</div><div>2. The new implementation of generics might break some existing `struct` and `class` code, for example if it is dependent on the exact size of an object because the class will have extra fields, one for each generic type, and therefore will be larger.</div><div><br></div><div>Disadvantages:</div><div><br></div><div>1. Major change.</div><div>2. Object size increases.</div><div><br>Thanks in advance for any comments,</div><div><br></div><div> — Howard.</div><div><br></div><div>PS This is part of a collection of proposals previously presented as “Protocols on Steroids”.</div><br><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=7XtDdMHRjqIUi4tzSjSp2pWQIyxYdP6woIWn4vwV5gfxpwEOVTzo92oepwWEcVNXvCsAW-2Forxg3RDuQnXnEKJE1s61ZQwLPbtLU8pGzxj-2FYRz7HG603-2BvteZzN-2FPTE-2BVvH2Y1MpBClLouTMgkPIrn3bmtRyaN-2BlVXaxdYx3nXLlGA923nAnKw6ygzx9hKAiqI7QEvEdSOrUWzbPB0oD6vLVU33TI1MC2Gqq7jZganWM-3D" alt="" width="1" height="1" border="0" style="min-height:1px!important;width:1px!important;border-width:0px!important;margin:0px!important;padding:0px!important"></div>_______________________________________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div></blockquote></div><br></div><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=ZEz4qHYnXhPr3bBPu-2FxP4tN3HfWKL-2FtJpqkQ0gkOVSCJDEhwwmTWIc-2FPZIHE-2BDgWzA3g-2BaJP6Sw8H28SvviIuJ2817Qb0JpvkK-2BlD32q7SAUi2tpKobxWWWuzmZK34QWPdnSF0T02rVkiqIh3fJsp2h29F4CLJjkrLOjsUiFetAIeWUYTrLOY-2Fh22qGItsbAlwpT8IMXEltTyCZ4TUX7OnIKNEGiEf8AlX3LUOB1nXM-3D" alt="" width="1" height="1" border="0" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;min-height:1px!important;width:1px!important;border-width:0px!important;margin:0px!important;padding:0px!important"><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important"><span> </span>_______________________________________________</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">swift-evolution mailing list</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><a href="mailto:swift-evolution@swift.org" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank">swift-evolution@swift.org</a><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div><br></div><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=u-2BKOvgEboaW8I8R8XL-2B2j-2Bat6qtKtRpy8Ey1JFnvcPApKVIHF1-2F64CArgYUz3p8TuYYEkKQ1tdR4hshaOpWkFLAUOjqtliC01695jiNGS-2BC94oh2rmMhuGXeM-2BrjsnolYk0NZ3VHSYgq7DCYFkI4xuKrnhJPBc2zvCue3GPy7gMZa8XeKdbZVOp-2FIKm-2B4vg4aNDG0fHo23Hd90LZamPlE6P7hD-2FWj5RXHq3nRnIMdI8-3D" alt="" width="1" height="1" border="0" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;min-height:1px!important;width:1px!important;border-width:0px!important;margin:0px!important;padding:0px!important"><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important"><span> </span>_______________________________________________</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">swift-evolution mailing list</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><a href="mailto:swift-evolution@swift.org" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank">swift-evolution@swift.org</a><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div><br></div></div></div></blockquote></div><br></div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=Vm9j-2B2K6zLqxUFTO82XA8HV2TThDz5lA3-2F-2Fpeujw7DSmbkaEqLyYXZmNxyAv-2FRLwIq49UAXwXhOJ-2B9DMigTLNglg7Tospl97XtgWKuECn62JquxZCKnb3Hkwn5WsTxcdc7htP4rZ9jJSiloBCjHEj7PopIeGwKAqdi9CtTkhhiX24XWgQoKwKMPdW-2F14PNymmGHUi4c8z-2FPa7TdinNcKJFD-2FouiR4cErYMqAaELKnA0-3D" alt="" width="1" height="1" border="0" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important">
</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><br clear="all"><div><br></div>-- <br><div class="gmail_signature"> -- Howard.<br></div>
</div>