<div dir="ltr"><span style="font-size:12.8px">If I understand correctly, this still doesn&#39;t solve the problem exactly.  Wouldn&#39;t Self in this context refer to the class that implements MyProtocol?</span><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">The example I raised is just a single use-case I ran into, but I think the more general point is that there isn&#39;t a good way to tell the compiler that a closure parameter must belong to more than one protocol, or a type plus a protocol.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Here&#39;s another (somewhat contrived) example:</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Say I was writing an application like IMDB, and I had a protocol for directors and another for writers:</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">    protocol Director {</div><div style="font-size:12.8px">        func directingCredits() -&gt; [Film]</div><div style="font-size:12.8px">    }</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">    protocol Writer {</div><div style="font-size:12.8px">        func writingCredits() -&gt; [Film]</div><div style="font-size:12.8px">    }</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">And I want to have a closure which returns all the movies written and directed by the same person:</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">    var getWrittenAndDirectedFilms : (&lt;Writer, Director&gt;)-&gt;[Film] = { writerDirector in</div><div style="font-size:12.8px">        return  writerDirector.writingCredits().filter { writerDirector.directingCredits().contains($0) }</div><div style="font-size:12.8px">    }</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Not all writers are directors, and not all directors are writers, but it&#39;s perfectly reasonable to have an operation which only works on objects which conform to those two protocols.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">It&#39;s easy to write a plain function that handles this use case using generics, but it&#39;s not possible with a closure.  It seems like an unnecessary limitation. </div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jan 15, 2016 at 6:01 PM, Félix Cloutier <span dir="ltr">&lt;<a href="mailto:felixcca@yahoo.ca" target="_blank">felixcca@yahoo.ca</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>Are you sure that your problem is about generics on lambdas? Seems to me that you wouldn&#39;t need generic lambdas if you could solve your initial problem in a different way.</div><div><br></div>You can use Self in protocols, which refers to the implementing type:<div><br></div><div><div></div><blockquote type="cite"><div>protocol MyProtocol {</div><div><span style="white-space:pre-wrap">        </span>var protocolControllerCallback: Self -&gt; Void { get }</div><div>}</div><div><br></div><div>class MyController: MyProtocol {</div><div><span style="white-space:pre-wrap">        </span>var protocolControllerCallback: MyController -&gt; Void</div><div><span style="white-space:pre-wrap">        </span></div><div><span style="white-space:pre-wrap">        </span>init() {</div><div><span style="white-space:pre-wrap">                </span>protocolControllerCallback = { cnt in return }</div><div><span style="white-space:pre-wrap">        </span>}</div><div>}</div></blockquote><div><br></div>That doesn&#39;t work right now because Swift will complain that the class must be `final` for reasons that sound bogus to me: &quot;it uses &#39;Self&#39; in a non-parameter, non-result type position&quot;. I don&#39;t know if there&#39;s a technical reason that it can&#39;t be in a closure parameter. Still seems to get you closer to what you want.</div><div><div>
<br><span style="color:rgb(0,0,0);font-family:&#39;Lucida Grande&#39;;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;display:inline!important;float:none">Félix</span>
</div>

<br><div><blockquote type="cite"><div><div class="h5"><div>Le 15 janv. 2016 à 05:07:06, Spencer Kohan via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; a écrit :</div><br></div></div><div><div><div class="h5"><div dir="ltr">New here, hope I&#39;m doing this right.
<div><br></div><div>I recently found a use case which does not appear to be covered by the swift language: it appears that there&#39;s no way to declare a closure type with generic arguments.</div><div><br></div><div>For example, what if I&#39;m building an iOS app, and I want to define a closure which operates on UIViewControllers which implement a particular protocol?<br></div><div><br></div><div>In ObjectiveC, this would be possible with the following syntax:</div><div><br></div><div>    typedef void (^MyBlockType)(UIViewController&lt;MyProtocol&gt;)</div><div><br></div><div>In Swift you can do this in the context of a function, class or struct:</div><div><br></div><div>    func myFunction&lt;T: UIViewController where T:MyProtocol&gt;() {</div><div>        let x : (T) -&gt; () = { generic in</div><div>           ....</div><div>        }</div><div>    }</div><div><br></div><div>But what if you want to declare such a closure as a variable within the protocol it&#39;s referring to?</div><div><br></div><div>    protocol MyProtocol {</div><div>        var protocolControllerCallback : (protocolController : ???? )-&gt;()</div><div>    }</div><div><br></div><div>It seems like Associated Types are the intended tool for this job, so you could have something like:</div><div><br>    protocol MyProtocol {</div><div>        typealias ProtocolObservingController</div><div>        var protocolControllerCallback : (protocolController : ProtocolObservingController )-&gt;() {get set}</div><div>    }</div><div><br></div><div>    class MyController : UIViewController, MyProtocol {</div><div>        typealias ProtocolObservingController = MyController</div><div>        ...</div><div>    }</div><div><br></div><div>But this doesn&#39;t quite solve the problem: we still can&#39;t have a closure defined in this protocol which can operate on *any* implementations of the protocol.  For instance, what if we wanted to pass a closure between two different implementations?</div><div><br></div><div>    class MyChildController : UIViewController, MyProtocol {</div><div>        typealias ProtocolObservingController = MyChildController</div><div>        ...</div><div>    }</div><div><br></div><div><div>    class MyParentController : UIViewController, MyProtocol {</div><div>        typealias ProtocolObservingController = MyParentController</div><div>        ...</div><div><br></div><div>        func createChildController() -&gt; MyControllerChild {</div><div>            let child = MyChildController()</div><div>            child.protocolControllerCallback = self.protocolControllerCallback</div><div>        }</div><div><br></div><div>    }</div></div><div><br></div><div>It doesn&#39;t work because the types of protocolControllerCallback are inconsistent between the two classes.</div><div><br></div><div>This feels like a hole in the language.</div><div><br></div><div><br></div><div><br></div><div><br></div></div>
</div></div><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=iRI3beHTe3UxYAHTlV3lA38zIPfHMhyuRzgTmGKV6k4aCoAQZUIFePb7DSEP1BFSBFa9noVtcNSceUSF5Efg5XbsIaCciTuKiWCR55Hnalx0GWqOfNtwhoB5ANOQbZbR9xzfrar-2BDhMfMxXSUDFqwGr6ES6Ffsmjh-2FleexHeQ9JVGElR6plMfgPvpcnUNJ8vom76Oi5ThLNqg9pOb7LRIZd-2Bjo2rVbTKO1VIq4wHB9I-3D" alt="" width="1" height="1" border="0" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important">
_______________________________________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div></blockquote></div><br></div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature">Spencer Kohan<br>cell: 216 288 8258</div>
</div>