<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=""><blockquote type="cite" class="">On Jan 20, 2016, at 11:26 PM, Slava Pestov <<a href="mailto:spestov@apple.com" class="">spestov@apple.com</a>> wrote:<br class=""></blockquote><div><blockquote type="cite" class=""><br class="Apple-interchange-newline"><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px; float: none; display: inline !important;" class="">Here’s an attempt to implement this with existing language features:</span><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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-stroke-width: 0px;"><blockquote type="cite" class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="">protocol HasElementType {</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class=""> func getElement() -> Any.Type?</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="">}</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><span class=""></span><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="">extension HasElementType {</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class=""> func getElement() -> Any.Type? {</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class=""> return nil</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class=""> }</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="">}</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><span class=""></span><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="">extension Array : HasElementType {</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class=""> func getElement() -> Any.Type? {</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class=""> return Element.self</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class=""> }</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="">}</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><span class=""></span><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="">func isArrayWithElementType<T>(a: Any, _ m: T.Type) -> Bool {</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class=""> guard let aa = a as? HasElementType else { return false }</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class=""> guard let elt = aa.getElement() else { return false }</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class=""> return elt is T.Type</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="">}</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><span class=""></span><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="">protocol P {}</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="">struct X : P {}</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;"><span class=""></span><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="">print(isArrayWithElementType([1,2,3,4,5], Int.self))</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="">print(isArrayWithElementType([1,2,3,4,5], Float.self))</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="">print(isArrayWithElementType(["a", "b"], String.self))</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="">print(isArrayWithElementType([X()], X.self))</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="">print(isArrayWithElementType([X()], P.self))</span></div></blockquote></div></div></blockquote></div><br class=""><div class="">Thanks for that. The trouble is that the problem I’m trying to solve is actually more complicated than the example; it’s not actually Array that I’m dealing with, but a custom type. I am looking for a way not just to see whether the thing contains a certain type, but actually to cast it to the generic type with ‘as?’ so that I can use it as the generic type, pass it to functions that want that generic type, etc., do things with its type T that require something somewhere knowing what the type is (in my example, I used arr.append(T()), an operation that needs to know what type T is, so that it can create the instance. Just creating a Foo() wouldn’t work, since the array could be of some Foo subclass and not take garden-variety Foos.</div><div class=""><br class=""></div><div class="">If we want to get *really* specific, I’m actually dealing with a protocol with associated types, not a generic struct. However, they both fall under the same umbrella of “need to use this as a generic constraint”, and “generic” is less obnoxious to type over and over when discussing things than “protocol with associated types”. :-P</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><div class=""><div class="">if let arr = someObject as? <T: Foo> Array<T> {<br class=""></div></div></blockquote><div class=""><br class=""></div>Yeah, it’s going to have to be this, since <T : Foo> is shorthand for <T where T : Foo>, and in general the <> of a bound generic type reference are different from <> in a generic signature — the latter introduces new type variables for instance.</blockquote><br class=""></div><div class="">Okay, in the example above, that leaves five places for the generic signature to go: after the “if”, after the “let”, after the variable name, after the equals sign, and after the “as?”. Or perhaps we could introduce some sort of new keyword in there to which to attach the generic signature.</div><div class=""><br class=""></div><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class=""></div></div></blockquote><blockquote type="cite" class=""><blockquote type="cite" class=""><div class=""><div class="">Is this a feasible thing to ask for?<br class=""></div></div></blockquote><div class=""><br class=""></div>I think so, but we have to careful with the design. This ties in with some of the discussions on generalizing existential types, also.</blockquote></div></div><div class=""><br class=""></div><div class="">That’s good to hear. Is there any information on what the Swift team is planning to do with existentials?</div><div class=""><br class=""></div><div class="">Charles</div><div class=""><br class=""></div></body></html>