<div>Huge +1 here.</div><div><br></div><div>To bring powerful functional approach to Swift I strongly feel like it&#39;s a must have.</div><div><br></div><div>Issue demonstration:</div><div>//co/invariance type</div><div>typealias FooFun&lt;-A, +R&gt; = (A)-&gt;R</div><div>//current types</div><div>typealias BarFun&lt;A, R&gt; = (A)-&gt;R</div><div><br></div><div>func exact(view:UIView) -&gt; UIView</div><div>func nonexact(view:NSObject) -&gt; UIControl</div><div><br></div><div>//ok</div><div>let magicFoo1:FooFun&lt;UIView, UIView&gt; = exact<br></div><div><div>//ok</div><div>let magicFoo2:FooFun&lt;UIView, UIView&gt; = nonexact</div></div><div><br></div><div>//ok</div><div>let magicBar1:BarFun&lt;UIView, UIView&gt; = exact<br></div><div><div>//FAIL</div><div>let magicBar2:BarFun&lt;UIView, UIView&gt; = nonexact</div></div><div><br></div><div>The last one fails, though function nonexact can do the job perfectly and there is no inconsistency as it accepts NSObject (UIView inherits from it so we are safe) and gives back UIControl (which is a subclass of UIView).</div><div><br></div><div>There are other examples with classes and functional stuff, but I hope I made the problem clear.</div><div><br></div><div><br><div class="gmail_quote"><div>On Fri, 9 Dec 2016 at 2:46 Braeden Profile via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg">Has the core team or the community considered the possibility of implementing covariant/contravariant generic types?  It would really be appreciated.<div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">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.  This is my exact use case here, using SceneKit to identify the first-hit Controller object:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#008f01" class="gmail_msg">class</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> ControllerNode&lt;Controller: AnyObject&gt;: </span><span style="font-variant-ligatures:no-common-ligatures;color:#aa2eb8" class="gmail_msg">SCNNode</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">{</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><span class="m_-8629733949641148535Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span></span><span style="font-variant-ligatures:no-common-ligatures;color:#008f01" class="gmail_msg">let</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> controller: </span><span style="font-variant-ligatures:no-common-ligatures;color:#498672" class="gmail_msg">Controller</span></div></div><div class="gmail_msg"><font face="Menlo" class="gmail_msg"><span style="font-size:11px" class="gmail_msg">}</span></font></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(146,146,146)" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">// Ordered front to back, returns the first Controller object.</span></div></div><div class="gmail_msg"><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#008f01" class="gmail_msg">for</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> hit </span><span style="font-variant-ligatures:no-common-ligatures;color:#008f01" class="gmail_msg">in</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> hitTest</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">{</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(146,146,146)" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures;color:#000000" class="gmail_msg"><span class="m_-8629733949641148535Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span></span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">// 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="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><span class="m_-8629733949641148535Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span></span><span style="font-variant-ligatures:no-common-ligatures;color:#008f01" class="gmail_msg">let</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> ancestrySequence = </span><span style="font-variant-ligatures:no-common-ligatures;color:#3d1d81" class="gmail_msg">sequence</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">(first: hit.</span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="gmail_msg">node</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">, next: { $0.</span><span style="font-variant-ligatures:no-common-ligatures;color:#703daa" class="gmail_msg">parent</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> })</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><b class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><span class="m_-8629733949641148535Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span></span><span style="font-variant-ligatures:no-common-ligatures;color:#008f01" class="gmail_msg">let</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> lastControllerNode: </span><span style="font-variant-ligatures:no-common-ligatures;color:#5faeae" class="gmail_msg">ControllerNode</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">&lt;</span><span style="font-variant-ligatures:no-common-ligatures;color:#aa2eb8" class="gmail_msg">AnyObject</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">&gt;? = ancestrySequence.</span><span style="font-variant-ligatures:no-common-ligatures;color:#3d1d81" class="gmail_msg">reduce</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">(</span><span style="font-variant-ligatures:no-common-ligatures;color:#008f01" class="gmail_msg">nil</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">)</span></b></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><b class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><span class="m_-8629733949641148535Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span>{ ($1 </span><span style="font-variant-ligatures:no-common-ligatures;color:#008f01" class="gmail_msg">as</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">? </span><span style="font-variant-ligatures:no-common-ligatures;color:#5faeae" class="gmail_msg">ControllerNode</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">) ?? $0 }</span></b></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span class="m_-8629733949641148535Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><span class="m_-8629733949641148535Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span></span><span style="font-variant-ligatures:no-common-ligatures;color:#008f01" class="gmail_msg">if</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#008f01" class="gmail_msg">let</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> cabinet = lastControllerNode?.</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">controller</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#008f01" class="gmail_msg">as</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">? </span><span style="font-variant-ligatures:no-common-ligatures;color:#5faeae" class="gmail_msg">CabinetController</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><span class="m_-8629733949641148535Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span>{ </span><span style="font-variant-ligatures:no-common-ligatures;color:#008f01" class="gmail_msg">return</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> cabinet }</span></div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><span class="m_-8629733949641148535Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span></span><br class="m_-8629733949641148535webkit-block-placeholder gmail_msg"></p><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><span class="m_-8629733949641148535Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span></span><span style="font-variant-ligatures:no-common-ligatures;color:#008f01" class="gmail_msg">if</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#008f01" class="gmail_msg">let</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> wall = lastControllerNode?.</span><span style="font-variant-ligatures:no-common-ligatures;color:#4f8187" class="gmail_msg">controller</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#008f01" class="gmail_msg">as</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">? </span><span style="font-variant-ligatures:no-common-ligatures;color:#5faeae" class="gmail_msg">WallController</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><span class="m_-8629733949641148535Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span>{ </span><span style="font-variant-ligatures:no-common-ligatures;color:#008f01" class="gmail_msg">return</span><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"> wall }</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg">}</span></div></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><br class="gmail_msg"></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo" class="gmail_msg"><span style="font-variant-ligatures:no-common-ligatures" class="gmail_msg"><div style="font-family:Helvetica;font-size:12px" class="gmail_msg">This compiles, but unfortunately, this will never work.  The `reduce` algorithm always ends up trying to convert things like `ControllerNode&lt;WallController&gt; as ControllerNode&lt;AnyObject&gt;`, which—unintuitively—always fails.  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="gmail_msg"><br class="gmail_msg"></div><div style="font-family:Helvetica;font-size:12px" class="gmail_msg">If Swift is supposed to welcome generic programming, this would be a great thing to have.</div></span></div></div>_______________________________________________<br class="gmail_msg"><br>swift-evolution mailing list<br class="gmail_msg"><br><a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg"><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg"><br></blockquote></div></div>