<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Feb 11, 2016, at 8:00 AM, Alex Hoppen via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">I really like your suggestion of functions conforming to a protocol. I thought about this a little while and how an extendable FunctionType (or Applicable as you called it) protocol may impact existing code. For that I would even go one step further and add another step of protocol indirection such that the function’s signature is just a specialised form of a protocol SignatureType (this allows even better syntax when extending FunctionType as you can see in my last example).</div><div class=""><br class=""></div><div class="">So this protocol would look like</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="color: rgb(187, 44, 162);" class="">protocol</span>&nbsp;FunctionSignatureType {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp;&nbsp;<span style="color: rgb(187, 44, 162);" class="">associatedtype</span><span style="color: rgb(187, 44, 162);" class=""><span style="" class="">&nbsp;Parameters</span></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp;&nbsp;<span style="color: rgb(187, 44, 162);" class="">associatedtype</span><span style="color: rgb(187, 44, 162);" class=""><span style="" class="">&nbsp;ReturnType</span></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div><div class=""><br class=""></div><div class=""><div class="">Parameters will be set to the functions parameters in tuple notation</div><div class=""><span style="font-family: Menlo; font-size: 11px;" class=""><br class=""></span></div><div class=""><span style="font-family: Menlo; font-size: 11px;" class="">(((</span><span style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);" class="">Int</span><span style="font-family: Menlo; font-size: 11px;" class="">,&nbsp;</span><span style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);" class="">String</span><span style="font-family: Menlo; font-size: 11px;" class="">), secondParameter:&nbsp;</span><span style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);" class="">Int</span><span style="font-family: Menlo; font-size: 11px;" class="">) -&gt;&nbsp;</span><span style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);" class="">String</span><span style="font-family: Menlo; font-size: 11px;" class="">).Input == ((</span><span style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);" class="">Int</span><span style="font-family: Menlo; font-size: 11px;" class="">,&nbsp;</span><span style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);" class="">String</span><span style="font-family: Menlo; font-size: 11px;" class="">), secondParameter:&nbsp;</span><span style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);" class="">Int</span><span style="font-family: Menlo; font-size: 11px;" class="">)</span></div></div><div class=""><br class=""></div><div class="">FunctionType would then only have one associated type:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">protocol</span> FunctionType {</div><div style="margin: 0px; line-height: normal;" class=""><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp;&nbsp;</span></font><font color="#bb2ca2" face="Menlo" class=""><span style="font-size: 11px;" class="">associatedtype</span></font><font face="Menlo" class=""><span style="font-size: 11px;" class="">&nbsp;Signature:&nbsp;</span></font><span style="font-family: Menlo; font-size: 11px;" class="">Function</span><span style="font-family: Menlo; font-size: 11px;" class="">SignatureType</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div><div class=""><br class=""></div><div class="">Signature could for example be&nbsp;<span style="font-family: Menlo; font-size: 11px;" class="">((</span><span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">Int, String), secondParameter: Int</span><span style="font-family: Menlo; font-size: 11px;" class="">) -&gt; </span><span style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;" class="">String</span>.</div><div class=""><br class=""></div><div class="">We could then declare the apply function as a simple extension to FunctionType just like you suggested</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">extension</span><span style="" class=""> </span>FunctionType<span style="" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp;&nbsp;<span style="color: rgb(187, 44, 162);" class="">func</span><span style="" class=""> apply(tuple: </span><font color="#703daa" class="">Signature</font><span style="" class="">.</span><font color="#703daa" class="">Parameters</font><span style="" class="">) -&gt; </span><font color="#703daa" class="">Signature</font><span style="" class="">.</span><font color="#703daa" class="">ReturnType</font><span style="" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp;&nbsp;<span style="color: rgb(0, 132, 0);" class="">// Add some compiler magic here</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div></div></div></div></blockquote><div><br class=""></div><div>I really like the idea of a FuncionType protocol. &nbsp;However, `apply` should be a requirement, not just in an extension. &nbsp;This would allow other types to conform to the protocol. &nbsp;</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><br class=""></div><div class="">This would make apply another normal Swift function with a special implementation just like print, + and so on. I think that providing the ability to extend FunctionTypes would be a huge win, because several functions that used to be global could now just be methods on FunctionType. For example to execute a function asynchronously via GCD could now be declared as:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">extension</span> <span style="font-variant-ligatures: no-common-ligatures; color: #4f8187" class="">FunctionType</span> <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">where</span> Signature == (() -&gt; Void) {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp;&nbsp;<span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">func</span> dispatchAsync(queue: <span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">dispatch_queue_t</span>) {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; &nbsp; dispatch_async(queue, <span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">self</span>)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">&nbsp; }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div><div class=""><br class=""></div><div class="">I don’t know how this fits into the compiler and if functions can be made to conform to a protocol anyway but from the outside this looks like a solution to me that fits very well in the current style of Swift.</div><div class=""><br class=""></div><div class="">- Alex</div><div class=""><div class=""><br class=""></div><div class=""><br class=""><div class=""><div class=""><blockquote type="cite" class=""><div class="">On 11 Feb 2016, at 08:54, Brent Royal-Gordon via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><blockquote type="cite" class="">Still find it quite confusing, because I expected x.methodName to be a bound method and here it's a special syntactic form. &nbsp;What happens if a protocol defines "func apply(to:)"? &nbsp;Is that legal? &nbsp;Would function types automatically conform to the protocol?<br class=""></blockquote><br class="">For `apply(to:)`, it really would just be a method available on function types. You could put an `apply(to:)` method on any other type, and it wouldn't have any effect on things. You could declare a protocol with `apply(to:)`, but it wouldn't do anything to any function types. Conceptually, there would only be a few special things about them:<br class=""><br class="">1. The compiler generates the `apply(to:)` methods automatically. We could, perhaps, have it generate a conformance to an `Applicable` protocol like this one, but that's probably overkill:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>protocol Applicable {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>typealias ReturnValue<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>typealias ArgumentTuple<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>func apply(to: ArgumentTuple) -&gt; ReturnValue<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""><br class="">(Actually, as I think about this, I wonder if `Applicable` could give us the `@splatting` property for free: take a generic parameter on Applicable and someone can specify a bare function, but you can't call it directly, only through its `apply(to:)` method.)<br class=""><br class="">2. If `fn` is overloaded, `fn.apply(x)` will end up selecting an `fn` overload based on the type of `x`. Concrete example: `(+).apply(tupleOfInts)` would give you the `Int, Int` implementation of the `+` operator.<br class=""><br class="">3. There's no way to add your own methods to a function type. (At least, I'm not proposing there would be. There's no particular reason we couldn't have other methods on functions, particularly if there's an `Applicable` protocol to extend.)<br class=""><br class="">But `apply` is not a keyword, `apply(to:)` does not receive any special parsing, and you can still splatter `apply`s all around your code with no consequences whatsoever. Honestly, that's the main virtue of the `apply(to:)` suggestion: that there's really very little to it.<br class=""><br class="">-- <br class="">Brent Royal-Gordon<br class="">Architechies<br class=""><br class="">_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></div></blockquote></div><br class=""></div></div></div></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>