<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="">I'm going to separate your examples into FooStruct and FooProtocol for clarity.</div><div class=""><br class=""></div><div class="">I agree that generics tend to propagate virally and I remember that at some point I wanted type erasure, though I don't remember for what exactly. The solution for `sayHi`, right now, is to make that one generic too:</div><div class=""><br class=""></div><div class=""></div><blockquote type="cite" class="">func sayHi<T>(to foo: T) where T: FooProtocol {<br class=""> print("hi \(foo.name)")<br class="">}</blockquote><br class=""><div class="">The "let foos: [FooStruct] = [FooStruct(name: "Int", value: 2), FooStruct(name: "Double", value: 2.0)]" part can't work for structs because arrays require each element to have the same size (but it could work for classes).</div><div class=""><br class=""></div><div class="">Even then, you couldn't infer the type to [FooClass<Any>] because contravariance isn't permissible in that situation: doing so would allow you to assign any Any to a FooClass's value.</div><div class=""><br class=""></div><div class="">Another problem that this would have to solve is that once you lose the associatedtype that came with the protocol, there is nothing you can do to recover it; you currently can't express "FooProtocol with T = Int" as a type that you can cast to, so you would only be able to pass the instance to functions that don't have constraints on T.</div><div class=""><br class=""></div><div class="">But all in all, with my current understanding of the issue, I think that I'm favorable to the idea.</div><div class=""><br class=""></div><div class="">Félix</div><div class=""><br class=""></div><div><blockquote type="cite" class=""><div class="">Le 7 août 2017 à 19:35, David Sweeris via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> a écrit :</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On Aug 7, 2017, at 3:00 PM, Logan Shire 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;">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 class="" style="color: rgb(194, 52, 155);">associatedtype </span><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);"> <span class="" style="color: rgb(194, 52, 155);">var</span> name: <span class="" style="color: rgb(0, 175, 202);">String </span>{ <span class="" style="color: rgb(194, 52, 155);">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 class="" style="color: rgb(194, 52, 155);">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].</div></div></div></blockquote><div class=""><br class=""></div><div class="">What happens if you try to say "foos: [Foo<Any>] = ..."? </div><div class=""><br class=""></div><div class=""><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="">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 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><span class="Apple-converted-space"> </span>foos = [<span class="" style="color: rgb(147, 201, 106);">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></div></blockquote></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">The idiomatic solution would be to create a `Named` protocol with a `var name: String {get}` property, and write your function like `func sayHi(to foo:Named) {...}`. However, this `Named`protocol is really pretty trivial -- its purpose is simply to "degenericify" a generic type, not to provide any semantic meaning. Perhaps an analogy could be drawn between such "trivial protocols" and how we sometimes view tuples as "trivial structs"? Dunno, maybe I'm just trying to turn two trees into a forest, but this kinda smells like it might be part of a bigger issue, and if it is I'd rather tackle that and then see if we still need to address anything here.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">+1, either way, though.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">- Dave Sweeris</div><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">_______________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; 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-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; 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-caps: 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-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">swift-evolution@swift.org</a><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; 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-caps: 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-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div><br class=""></body></html>