<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> Foo<T> {</div><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> name: <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);"> <span class="" style="color: rgb(194, 52, 155);">let</span> value: <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> Foo {</div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(255, 255, 255); background-color: rgb(40, 43, 53);"> <span style="color: rgb(194, 52, 155);" class="">associatedtype </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);"> <span class="" style="color: rgb(194, 52, 155);">var</span> name: <span class="" style="color: rgb(0, 175, 202);">String </span>{ <span style="color: rgb(194, 52, 155);" class="">get </span>}</div><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);">var</span> value: <span class="" style="color: rgb(147, 201, 106);">T </span>{ <span style="color: rgb(194, 52, 155);" class="">get </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> sayHi(to foo: <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);"> <span class="" style="color: rgb(0, 175, 202);">print</span>(<span class="" style="color: rgb(228, 67, 71);">"hi </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 <…>”</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> foos: [Foo] = [<span class="" style="color: rgb(147, 201, 106);">Foo</span>(name: <span class="" style="color: rgb(228, 67, 71);">"Int"</span>, value: <span class="" style="color: rgb(139, 132, 207);">2</span>), <span class="" style="color: rgb(147, 201, 106);">Foo</span>(name: <span class="" style="color: rgb(228, 67, 71);">"Double"</span>, value: <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);"> 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: </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: </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);">), </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: </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: </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. </div><div class="">I.e. if you have a type Foo<T>, 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<String, Foo>)</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<T> should be able to be implicitly casted to Foo wherever you want, and Foo could be cast to Foo<T> 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> names = <span class="" style="color: rgb(147, 201, 106);">foos</span>.<span class="" style="color: rgb(0, 175, 202);">map</span> { $0.<span class="" style="color: rgb(147, 201, 106);">name</span> }</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>