<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="">One of my longstanding frustrations with generic types and protocols has been how hard it is to work with them when their type is unspecified.<div class="">Often I find myself wishing that I could write a function that takes a generic type or protocol as a parameter, but doesn’t care what its generic type is.</div><div class=""><br class=""></div><div class="">For example, if I have a type:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);"><span class="" style="color: rgb(194, 52, 155);">struct</span>&nbsp;Foo&lt;T&gt; {</div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);">&nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(194, 52, 155);">let</span>&nbsp;name:&nbsp;<span class="" style="color: rgb(0, 175, 202);">String</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);">&nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(194, 52, 155);">let</span>&nbsp;value:&nbsp;<span class="" style="color: rgb(147, 201, 106);">T</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);">}</div></div><div class=""><br class=""></div><div class="">or:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);"><span class="" style="color: rgb(194, 52, 155);">protocol</span>&nbsp;Foo {</div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);">&nbsp; &nbsp;&nbsp;<span style="color: rgb(194, 52, 155);" class="">associatedtype&nbsp;</span><span style="color: rgb(147, 201, 106);" class="">T</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);">&nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(194, 52, 155);">var</span>&nbsp;name:&nbsp;<span class="" style="color: rgb(0, 175, 202);">String&nbsp;</span>{&nbsp;<span style="color: rgb(194, 52, 155);" class="">get&nbsp;</span>}</div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);">&nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(194, 52, 155);">var</span>&nbsp;value:&nbsp;<span class="" style="color: rgb(147, 201, 106);">T&nbsp;</span>{&nbsp;<span style="color: rgb(194, 52, 155);" class="">get&nbsp;</span>}</div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);">}</div></div><div class=""><br class=""></div><div class="">And I want to write a function that only cares about Foo.name, I’d like to be able to:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);"><span class="" style="color: rgb(194, 52, 155);">func</span>&nbsp;sayHi(to foo:&nbsp;<span class="" style="text-decoration: underline; color: rgb(0, 175, 202);">F</span><span class="" style="color: rgb(0, 175, 202);">oo</span>) {</div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);">&nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(0, 175, 202);">print</span>(<span class="" style="color: rgb(228, 67, 71);">"hi&nbsp;</span>\<span class="" style="color: rgb(228, 67, 71);">(</span>foo.name<span class="" style="color: rgb(228, 67, 71);">)"</span>)</div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);">}</div></div><div class=""><br class=""></div><div class="">But instead I get the error, “Reference to generic type Foo requires arguments in &lt;…&gt;”</div><div class=""><br class=""></div><div class="">Also, when you want to have a polymorphic array of generic types, you can’t:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);"><span class="" style="color: rgb(194, 52, 155);">let</span>&nbsp;foos: [Foo] = [<span class="" style="color: rgb(147, 201, 106);">Foo</span>(name:&nbsp;<span class="" style="color: rgb(228, 67, 71);">"Int"</span>, value:&nbsp;<span class="" style="color: rgb(139, 132, 207);">2</span>),&nbsp;<span class="" style="color: rgb(147, 201, 106);">Foo</span>(name:&nbsp;<span class="" style="color: rgb(228, 67, 71);">"Double"</span>, value:&nbsp;<span class="" style="color: rgb(139, 132, 207);">2.0</span>)]</div></div><div class=""><br class=""></div><div class="">And if you remove the explicit type coercion, you just get [Any]</div><div class=""><br class=""></div><div class=""><span class="" style="font-family: Menlo; background-color: rgb(40, 43, 53); color: rgb(194, 52, 155);">let</span><span class="" style="color: rgb(255, 255, 255); font-family: Menlo; background-color: rgb(40, 43, 53);">&nbsp;foos = [</span><span class="" style="font-family: Menlo; background-color: rgb(40, 43, 53); color: rgb(147, 201, 106);">Foo</span><span class="" style="color: rgb(255, 255, 255); font-family: Menlo; background-color: rgb(40, 43, 53);">(name:&nbsp;</span><span class="" style="font-family: Menlo; background-color: rgb(40, 43, 53); color: rgb(228, 67, 71);">"Int"</span><span class="" style="color: rgb(255, 255, 255); font-family: Menlo; background-color: rgb(40, 43, 53);">, value:&nbsp;</span><span class="" style="font-family: Menlo; background-color: rgb(40, 43, 53); color: rgb(139, 132, 207);">2</span><span class="" style="color: rgb(255, 255, 255); font-family: Menlo; background-color: rgb(40, 43, 53);">),&nbsp;</span><span class="" style="font-family: Menlo; background-color: rgb(40, 43, 53); color: rgb(147, 201, 106);">Foo</span><span class="" style="color: rgb(255, 255, 255); font-family: Menlo; background-color: rgb(40, 43, 53);">(name:&nbsp;</span><span class="" style="font-family: Menlo; background-color: rgb(40, 43, 53); color: rgb(228, 67, 71);">"Double"</span><span class="" style="color: rgb(255, 255, 255); font-family: Menlo; background-color: rgb(40, 43, 53);">, value:&nbsp;</span><span class="" style="font-family: Menlo; background-color: rgb(40, 43, 53); color: rgb(139, 132, 207);">2.0</span><span class="" style="color: rgb(255, 255, 255); font-family: Menlo; background-color: rgb(40, 43, 53);">)]</span></div><div class=""><br class=""></div><div class="">I wish that could be inferred to be [Foo]. I’d like to propose being able to use the non-generic interface of a type normally.&nbsp;</div><div class="">I.e. if you have a type Foo&lt;T&gt;, it is implicitly of type Foo as well. The type Foo could be used like any other type.</div><div class="">It could be a parameter in a function, a variable, or even the generic type of another type (like a Dictionary&lt;String, Foo&gt;)</div><div class=""><br class=""></div><div class="">The only restriction is that if you want to call or access, directly or indirectly, a function or member that requires the generic type,</div><div class="">the generic type would have to be known at that point.</div><div class=""><br class=""></div><div class="">Foo&lt;T&gt; should be able to be implicitly casted to Foo wherever you want, and Foo could be cast to Foo&lt;T&gt; conditionally.</div><div class="">Initializers would still obviously have to know the generic type, but given the above example, you should be able to:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);"><span class="" style="color: rgb(194, 52, 155);">let</span>&nbsp;names =&nbsp;<span class="" style="color: rgb(147, 201, 106);">foos</span>.<span class="" style="color: rgb(0, 175, 202);">map</span>&nbsp;{ $0.<span class="" style="color: rgb(147, 201, 106);">name</span>&nbsp;}</div></div><div class=""><br class=""></div><div class="">However, you could not do the following:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);" class=""><span style="color: #c2349b" class="">let</span> foos = [<span style="color: #93c96a" class="">Foo</span>]()</div></div><div class=""><br class=""></div><div class="">Because the initializer would need to know the generic type in order to allocate the memory.</div><div class=""><br class=""></div><div class="">Let me know what you think!</div><div class=""><br class=""></div><div class="">—</div><div class=""><br class=""></div><div class="">Logan Shire</div><div class="">iOS @ Lyft</div><div class=""><br class=""></div></body></html>