<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Agreed on both counts. Generics are more familiar but don't actually cover the use cases where the associated type is <i class="">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 class=""><br class=""></div><div class="">Jordan</div><div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 12, 2016, at 8:17, Austin Zheng via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><span 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; float: none; display: inline !important;" class="">Strong -1, covariance on generics should be explicitly opt-in. Also -1 on generics replacing associated types in protocols.</span><div class="" 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;"><br class=""></div><div class="" 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;">Austin</div><div class="" 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;"><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jan 12, 2016, at 1:45 AM, Howard Lovatt via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="margin: 0px; line-height: normal;"><font face="Menlo" class=""><span class="" 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 class="" style="margin: 0px; line-height: normal;"><font face="Menlo" class=""><span class="" style="font-size: 11px;"><br class=""></span></font></div><div class="" style="margin: 0px; line-height: normal;"><font face="Menlo" class=""><span class="" style="font-size: 11px;">1st a demonstration of the current situation of invariant generics:</span></font></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""><br class=""></span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> </span>// Current system</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">class</span><span class="Apple-converted-space"> </span>Top {}</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">class</span><span class="Apple-converted-space"> </span>Bottom:<span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">Top</span><span class="Apple-converted-space"> </span>{}</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;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">struct</span><span class="Apple-converted-space"> </span>Box<T: AnyObject> {</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">var</span><span class="Apple-converted-space"> </span>value:<span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">T</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">init</span>(<span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">_</span><span class="Apple-converted-space"> </span>initialValue:<span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">T</span>) {</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">value</span><span class="Apple-converted-space"> </span>= initialValue;</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;"> }</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;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">let</span><span class="Apple-converted-space"> </span>boxB =<span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">Box</span>(<span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">Bottom</span>())</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span>// let boxT: Box<Top> = boxB // Covariance currently not allowed</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; min-height: 13px;">The key point is although `Bottom` 'is a’ `Top`, `Box<Bottom>` *is not* a `Box<Top>`.</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; min-height: 13px;">I am suggesting:</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; min-height: 13px;">1. That `Box<Bottom>` should be a `Box<Top>` (covariance).</div><div class="" 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 class="" 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 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);"><span class=""> <span class="Apple-converted-space"> </span></span>// Proposal:</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span>// 1. No change to Box, i.e. programmer would just write Box as before</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span>// 2. Code transformed by comiler with write check for each specific, generic type instance</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span>// Best approximation of resulting code in current Swift to demonstrate spirit of idea:</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);"><span class=""> <span class="Apple-converted-space"> </span></span>// Compiler writes a universal form using the upper bound (it writes the underlyting representation).</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </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 class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">struct</span><span class="Apple-converted-space"> </span>BoxAnyObject {</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span>// Generated from generic argument `<T: AnyObject>`.</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">let</span><span class=""><span class="Apple-converted-space"> </span>T:<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">AnyObject</span><span class="">.Type<span class="Apple-converted-space"> </span></span>// Store the actual type.</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"> <br class="webkit-block-placeholder"></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span>// Generated from stored property `var value: T` and noting that `T`'s upper bound is `AnyObject`.</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">private</span><span class=""><span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">var</span><span class=""><span class="Apple-converted-space"> </span>_value:<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">AnyObject</span><span class=""><span class="Apple-converted-space"> </span></span>// Access the stored property through a setter so that type can be checked</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">var</span><span class="Apple-converted-space"> </span>value:<span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">AnyObject</span><span class="Apple-converted-space"> </span>{</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">get</span><span class="Apple-converted-space"> </span>{</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">return</span><span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">_value</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;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">set</span><span class="Apple-converted-space"> </span>{</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span>// In all functions check that args declared as `T` are actually a `T` or a sub-type.</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span>// Note: `is` only works with type literal and there is no `>=` operator for types :(.</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span>// `is` would need changing or `>=` for types adding, nearest at moment `==`.</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27);"><span class=""> <span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(61, 29, 129);">precondition</span><span class="">(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">T</span><span class=""><span class="Apple-converted-space"> </span>==<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 132, 0);">/* >= */</span><span class=""><span class="Apple-converted-space"> </span>newValue.</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">dynamicType</span><span class="">,<span class="Apple-converted-space"> </span></span>"Type of newValue,<span class="Apple-converted-space"> </span><span class="">\</span>(<span class="">newValue.</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">dynamicType</span>), is not a sub-type of generic type T,<span class="Apple-converted-space"> </span><span class="">\</span>(<span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">T</span>)"<span class="">)</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">_value</span><span class="Apple-converted-space"> </span>= newValue</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;"> }</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"> <br class="webkit-block-placeholder"></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span>// Generated from `init(_ initialValue: T)` and noting that `T`'s upper bound is `AnyObject`.</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">init</span>(<span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">_</span><span class="Apple-converted-space"> </span>lowestCommonDeclaredT:<span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">AnyObject</span>.Type,<span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">_</span><span class="Apple-converted-space"> </span>initialValue:<span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(112, 61, 170);">AnyObject</span>) {</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">T</span><span class="Apple-converted-space"> </span>= lowestCommonDeclaredT</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">_value</span><span class="Apple-converted-space"> </span>= initialValue</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;"> }</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);"><span class=""> <span class="Apple-converted-space"> </span></span>// Demonstrate that all `Box`es are the same size and therefore can be bitwise copied</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span>// Compiler supplies lowest-common, declared, generic type for all the `T`s in the `init` call.</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">var</span><span class=""><span class="Apple-converted-space"> </span>bT =<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">BoxAnyObject</span><span class="">(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">Top</span><span class="">.</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">self</span><span class="">,<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">Top</span><span class="">())<span class="Apple-converted-space"> </span></span>// In practice user would write `let bT = Box(Top())`.</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">bT</span><span class="">.</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">T</span><span class=""><span class="Apple-converted-space"> </span></span>// Top.Type</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(61, 29, 129);"><span class=""> <span class="Apple-converted-space"> </span></span>sizeofValue<span class="">(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">bT</span><span class="">)<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 132, 0);">// 16</span></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);"><span class=""> <span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">var</span><span class=""><span class="Apple-converted-space"> </span>bB =<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">BoxAnyObject</span><span class="">(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">Bottom</span><span class="">.</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">self</span><span class="">,<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">Bottom</span><span class="">())<span class="Apple-converted-space"> </span></span>// In practice user would write `let bB = Box(Bottom())`.</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">bB</span><span class="">.</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">T</span><span class=""><span class="Apple-converted-space"> </span></span>// Bottom.Type</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(61, 29, 129);"><span class=""> <span class="Apple-converted-space"> </span></span>sizeofValue<span class="">(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">bB</span><span class="">)<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 132, 0);">// 16</span></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);"><span class=""> <span class="Apple-converted-space"> </span></span>// Demonstration covariance.</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">bT</span><span class=""><span class="Apple-converted-space"> </span>=<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">bB</span><span class=""><span class="Apple-converted-space"> </span></span>// Compiler would check covariance of declared generic types.</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">bT</span><span class="">.</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">T</span><span class=""><span class="Apple-converted-space"> </span></span>// Bottom.Type</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);"><span class=""> <span class="Apple-converted-space"> </span></span>// Demonstrate generic returned type</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span>// Compiler would add cast to declared, generic type.</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">bB</span><span class="">.</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">value</span><span class=""><span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">as</span><span class="">!<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">Bottom</span><span class=""><span class="Apple-converted-space"> </span></span>// In practice user would write `bB.value`.</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);"><span class=""> <span class="Apple-converted-space"> </span></span>// Demonstrate type safety</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">bT</span><span class=""><span class="Apple-converted-space"> </span>=<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">BoxAnyObject</span><span class="">(</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">Top</span><span class="">.</span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(187, 44, 162);">self</span><span class="">,<span class="Apple-converted-space"> </span></span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">Top</span><span class="">())<span class="Apple-converted-space"> </span></span>// In practice user would write `bT = Box(Top())`.</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">bT</span>.<span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">value</span><span class="Apple-converted-space"> </span>=<span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(79, 129, 135);">Top</span>()<span class="Apple-converted-space"> </span><span class="" style="font-variant-ligatures: no-common-ligatures; color: rgb(0, 132, 0);">// OK</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span>// bT.value = Bottom() // Doesn't work at present because need `>=` for types, but would work in practice</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class=""> <span class="Apple-converted-space"> </span></span>// bB.value = Top() // Runtime error - wrong type</div><div class=""><br class=""></div><div class="">The implications of this proposal are:</div><div class=""><br class=""></div><div class="">1. The compiler can statically type check a read from a stored property.</div><div class="">2. A write to a stored property is type checked at runtime.</div><div class="">3. Protocols can be made generic instead of having an associated type and then they become a proper type with dynamic dispatch.</div><div class="">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 class="">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 class="">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 class="">7. There are whole types, `AnySequence`, `AnyGenerator`, etc., that would be replaced by a generic protocols, `Sequence`, `Generator`, etc.</div><div class=""><br class=""></div><div class="">Advantages:</div><div class=""><br class=""></div><div class="">1. Covariant generics are a powerful addition to the language.</div><div class="">2. Generics’ invariance are inconsistent with the rest of the language.</div><div class="">3. Generic protocols would become a ‘proper’ type and you could have arrays and fields of a generic protocol.</div><div class="">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 class=""><br class=""></div><div class="">Compatibility:</div><div class=""><br class=""></div><div class="">1. This would be a major change since associated types in protocols would be replaced by generics.</div><div class="">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 class=""><br class=""></div><div class="">Disadvantages:</div><div class=""><br class=""></div><div class="">1. Major change.</div><div class="">2. Object size increases.</div><div class=""><br class="">Thanks in advance for any comments,</div><div class=""><br class=""></div><div class=""> — Howard.</div><div class=""><br class=""></div><div class="">PS This is part of a collection of proposals previously presented as “Protocols on Steroids”.</div><br class=""><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" class="" style="height: 1px !important; width: 1px !important; border-width: 0px !important; margin: 0px !important; padding: 0px !important;"></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><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; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; height: 1px !important; width: 1px !important; border-width: 0px !important; margin: 0px !important; padding: 0px !important;" class=""><span 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; float: none; display: inline !important;" class=""><span class="Apple-converted-space"> </span>_______________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="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; float: none; display: inline !important;" class="">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; 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=""><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; 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="">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; 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=""><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; 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="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div><br class=""></div></body></html>