<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 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> FunctionSignatureType {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color: rgb(187, 44, 162);" class="">associatedtype</span><span style="color: rgb(187, 44, 162);" class=""><span style="color: rgb(0, 0, 0);" class=""> Parameters</span></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color: rgb(187, 44, 162);" class="">associatedtype</span><span style="color: rgb(187, 44, 162);" class=""><span style="color: rgb(0, 0, 0);" class=""> 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="">, </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: </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><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="">, </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: </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=""> </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=""> Signature: </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 <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="">) -> </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="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span>FunctionType<span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <span style="color: rgb(187, 44, 162);" class="">func</span><span style="color: rgb(0, 0, 0);" class=""> apply(tuple: </span><font color="#703daa" class="">Signature</font><span style="color: rgb(0, 0, 0);" class="">.</span><font color="#703daa" class="">Parameters</font><span style="color: rgb(0, 0, 0);" class="">) -> </span><font color="#703daa" class="">Signature</font><span style="color: rgb(0, 0, 0);" class="">.</span><font color="#703daa" class="">ReturnType</font><span style="color: rgb(0, 0, 0);" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""> <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=""> }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div><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 == (() -> Void) {</div><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="">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=""> 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=""> }</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><blockquote type="cite" class=""><div class="">On 11 Feb 2016, at 08:54, Brent Royal-Gordon 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=""><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. What happens if a protocol defines "func apply(to:)"? Is that legal? 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) -> 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="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></div></blockquote></div><br class=""></div></div></div></div></body></html>