<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="">Siesta’s Entity would certainly profit from being able to opt in to this mechanism:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;&nbsp;<a href="https://bustoutsolutions.github.io/siesta/api/Structs/Entity.html" class="">https://bustoutsolutions.github.io/siesta/api/Structs/Entity.html</a></div><div class=""><br class=""></div><div class="">It is _not_ a collection type and does not implement any collection-related protocols. However, the mechanism would (I think?) be essentially the same as for collections. So I’m not sure whether this is an example for or against Doug’s remarks that you quoted.</div><div class=""><br class=""></div><div class="">Cheers, P</div><div class=""><br class=""></div><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 9, 2016, at 1:24 PM, Hooman Mehr via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">For the specific case of custom collections, I think it is worth providing a protocol as Doug noted before.<div class=""><br class=""></div><div class="">Quoting Doug Gregor (1/13/16, thread: "<font color="rgba(0, 0, 0, 0.85098)" face="Helvetica Neue" class="">Make generics covariant and add generics to protocols”)</font>:&nbsp;</div><div class=""><blockquote type="cite" class="">Swift’s value-semantic collections are covariant in their generic parameters, which we do through some fairly tight coupling between the compiler and standard library. From a theoretical standpoint, I’m very happy with the way value-semantic collections provide subtyping and mutation while maintaining soundness (== no runtime checks needed), and for me <b class=""><i class="">I would consider it “enough” if we were to formalize that compiler/collection type interaction with some kind of protocol so other collection types could opt in to subtyping</i></b>, because I don’t think variance—as a language feature—carries its weight outside of the fairly narrow collection-subtyping cases.<br class=""></blockquote><div class="">(Emphasis mine)&nbsp;</div><div class=""><br class=""></div><div class="">I also agree with Doug and you that&nbsp;variance does not carry its weight outside of collection-subtyping cases.</div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Dec 9, 2016, at 10:41 AM, Robert Widmann via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div dir="auto" class=""><div class="">I keep seeing collections brought up whenever this is discussed, so my question is: Have you found a broader use for variance annotations in the Swift you write? &nbsp;Even in Objective-C (perhaps due to their relative obscurity) I don't see (non-Foundation) people make use of the variance annotations for generic classes, so it makes me think we could just implement this as an extension to the collection casting machinery instead of exposing a Scala-esque variance notation. &nbsp;Sort of like how it was done before when subtyping was introduced for function types around 2.x IIRC.</div><div class=""><br class="">~Robert Widmann</div><div class=""><br class="">2016/12/08 19:45、Braeden Profile via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; のメッセージ:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class="">Has the core team or the community considered the possibility of implementing covariant/contravariant generic types? &nbsp;It would really be appreciated.<div class=""><br class=""></div><div class="">I know with Array, vague-ifying or specific-ifying the type ([Int] to [Any]) has help from the compiler—and we can use `map` if all else fails—but that only lessens the impact of the missing functionality. &nbsp;This is my exact use case here, using SceneKit to identify the first-hit Controller object:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #008f01" class="">class</span><span style="font-variant-ligatures: no-common-ligatures" class=""> ControllerNode&lt;Controller: AnyObject&gt;: </span><span style="font-variant-ligatures: no-common-ligatures; color: #aa2eb8" class="">SCNNode</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">{</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="font-variant-ligatures: no-common-ligatures; color: #008f01" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> controller: </span><span style="font-variant-ligatures: no-common-ligatures; color: #498672" class="">Controller</span></div></div><div class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">}</span></font></div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(146, 146, 146);" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">// Ordered front to back, returns the first Controller object.</span></div></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #008f01" class="">for</span><span style="font-variant-ligatures: no-common-ligatures" class=""> hit </span><span style="font-variant-ligatures: no-common-ligatures; color: #008f01" class="">in</span><span style="font-variant-ligatures: no-common-ligatures" class=""> hitTest</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">{</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(146, 146, 146);" class=""><span style="font-variant-ligatures: no-common-ligatures;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="font-variant-ligatures: no-common-ligatures" class="">// Determine if this node is part of a controller.</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="font-variant-ligatures: no-common-ligatures; color: #008f01" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> ancestrySequence = </span><span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">sequence</span><span style="font-variant-ligatures: no-common-ligatures" class="">(first: hit.</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">node</span><span style="font-variant-ligatures: no-common-ligatures" class="">, next: { $0.</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">parent</span><span style="font-variant-ligatures: no-common-ligatures" class=""> })</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><b class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="font-variant-ligatures: no-common-ligatures; color: #008f01" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> lastControllerNode: </span><span style="font-variant-ligatures: no-common-ligatures; color: #5faeae" class="">ControllerNode</span><span style="font-variant-ligatures: no-common-ligatures" class="">&lt;</span><span style="font-variant-ligatures: no-common-ligatures; color: #aa2eb8" class="">AnyObject</span><span style="font-variant-ligatures: no-common-ligatures" class="">&gt;? = ancestrySequence.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">reduce</span><span style="font-variant-ligatures: no-common-ligatures" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #008f01" class="">nil</span><span style="font-variant-ligatures: no-common-ligatures" class="">)</span></b></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><b class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>{ ($1 </span><span style="font-variant-ligatures: no-common-ligatures; color: #008f01" class="">as</span><span style="font-variant-ligatures: no-common-ligatures" class="">? </span><span style="font-variant-ligatures: no-common-ligatures; color: #5faeae" class="">ControllerNode</span><span style="font-variant-ligatures: no-common-ligatures" class="">) ?? $0 }</span></b></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="font-variant-ligatures: no-common-ligatures; color: #008f01" class="">if</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #008f01" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> cabinet = lastControllerNode?.</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">controller</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #008f01" class="">as</span><span style="font-variant-ligatures: no-common-ligatures" class="">? </span><span style="font-variant-ligatures: no-common-ligatures; color: #5faeae" class="">CabinetController</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>{ </span><span style="font-variant-ligatures: no-common-ligatures; color: #008f01" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> cabinet }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span><br class="webkit-block-placeholder"></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span><span style="font-variant-ligatures: no-common-ligatures; color: #008f01" class="">if</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #008f01" class="">let</span><span style="font-variant-ligatures: no-common-ligatures" class=""> wall = lastControllerNode?.</span><span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">controller</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #008f01" class="">as</span><span style="font-variant-ligatures: no-common-ligatures" class="">? </span><span style="font-variant-ligatures: no-common-ligatures; color: #5faeae" class="">WallController</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><span class="Apple-tab-span" style="white-space:pre">                </span>{ </span><span style="font-variant-ligatures: no-common-ligatures; color: #008f01" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> wall }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><div style="font-family: Helvetica; font-size: 12px;" class="">This compiles, but unfortunately, this will never work. &nbsp;The `reduce` algorithm always ends up trying to convert things like `ControllerNode&lt;WallController&gt; as ControllerNode&lt;AnyObject&gt;`, which—unintuitively—always fails. &nbsp;Without compiler help, so would things like `myIntArray as [Any]` or `Optional&lt;Boy&gt;(Boy()) as Optional&lt;Human&gt;`.</div><div style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px;" class="">If Swift is supposed to welcome generic programming, this would be a great thing to have.</div></span></div></div></blockquote><blockquote type="cite" class=""><div class=""><span class="">_______________________________________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br class=""></div></blockquote></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div></div></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>