<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 11 Feb 2016, at 16:05, Matthew Johnson <<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><blockquote type="cite" class="" style="font-family: Helvetica; font-size: 13px; 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;"><div class=""><br class="Apple-interchange-newline">On Feb 11, 2016, at 8:00 AM, Alex Hoppen 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;"><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 class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="color: rgb(187, 44, 162);">protocol</span> FunctionSignatureType {</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="" style="color: rgb(187, 44, 162);">associatedtype</span><span class="" style="color: rgb(187, 44, 162);"><span class=""> Parameters</span></span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="" style="color: rgb(187, 44, 162);">associatedtype</span><span class="" style="color: rgb(187, 44, 162);"><span class=""> ReturnType</span></span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">}</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 class="" style="font-family: Menlo; font-size: 11px;"><br class=""></span></div><div class=""><span class="" style="font-family: Menlo; font-size: 11px;">(((</span><span class="" style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);">Int</span><span class="" style="font-family: Menlo; font-size: 11px;">, </span><span class="" style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);">String</span><span class="" style="font-family: Menlo; font-size: 11px;">), secondParameter: </span><span class="" style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);">Int</span><span class="" style="font-family: Menlo; font-size: 11px;">) -> </span><span class="" style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);">String</span><span class="" style="font-family: Menlo; font-size: 11px;">).Input == ((</span><span class="" style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);">Int</span><span class="" style="font-family: Menlo; font-size: 11px;">, </span><span class="" style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);">String</span><span class="" style="font-family: Menlo; font-size: 11px;">), secondParameter: </span><span class="" style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);">Int</span><span class="" style="font-family: Menlo; font-size: 11px;">)</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 class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="color: rgb(187, 44, 162);">protocol</span><span class="Apple-converted-space"> </span>FunctionType {</div><div class="" style="margin: 0px; line-height: normal;"><font face="Menlo" class=""><span class="" style="font-size: 11px;"> </span></font><font color="#bb2ca2" face="Menlo" class=""><span class="" style="font-size: 11px;">associatedtype</span></font><font face="Menlo" class=""><span class="" style="font-size: 11px;"> Signature: </span></font><span class="" style="font-family: Menlo; font-size: 11px;">Function</span><span class="" style="font-family: Menlo; font-size: 11px;">SignatureType</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">}</div><div class=""><br class=""></div><div class="">Signature could for example be <span class="" style="font-family: Menlo; font-size: 11px;">((</span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">Int, String), secondParameter: Int</span><span class="" style="font-family: Menlo; font-size: 11px;">) -><span class="Apple-converted-space"> </span></span><span class="" style="color: rgb(112, 61, 170); font-family: Menlo; font-size: 11px;">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 class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);"><span class="" style="color: rgb(187, 44, 162);">extension</span><span class=""><span class="Apple-converted-space"> </span></span>FunctionType<span class=""><span class="Apple-converted-space"> </span>{</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="" style="color: rgb(187, 44, 162);">func</span><span class=""><span class="Apple-converted-space"> </span>apply(tuple:<span class="Apple-converted-space"> </span></span><font color="#703daa" class="">Signature</font><span class="">.</span><font color="#703daa" class="">Parameters</font><span class="">) -><span class="Apple-converted-space"> </span></span><font color="#703daa" class="">Signature</font><span class="">.</span><font color="#703daa" class="">ReturnType</font><span class=""><span class="Apple-converted-space"> </span>{</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="" style="color: rgb(0, 132, 0);">// Add some compiler magic here</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> }</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">}</div></div></div></div></div></blockquote><div style="font-family: Helvetica; font-size: 13px; 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;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 13px; 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;" class="">I really like the idea of a FuncionType protocol. However, `apply` should be a requirement, not just in an extension. This would allow other types to conform to the protocol. </div><br class="" style="font-family: Helvetica; font-size: 13px; 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;"></div></blockquote><div><br class=""></div><div>Good point, it seems like I haven’t completely considered other types conforming to FunctionType. </div><div>If we provided a default implementation for apply that uses a special implementation only applicable to real functions we would have to make sure that this implementation is never used for custom types conforming to FunctionType. I can currently think of two options to achieve this:</div><div>1. Create a new private protocol in the stdlib extending FunctionType to which the functions actually conform and provide a default implementation for that protocol only</div><div>2. Make FunctionType a struct instead of a protocol (and call it Function instead). But I have no idea what implications that poses to the compiler. Making functions conform to FunctionType already seems hard to me and this even harder… If it would be possible I would prefer this option. Functions would then nicely line up along with Int etc.</div><br class=""><blockquote type="cite" class=""><div class=""><blockquote type="cite" class="" style="font-family: Helvetica; font-size: 13px; 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;"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><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 class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><span class="" style="color: rgb(187, 44, 162);">extension</span><span class="Apple-converted-space"> </span><span class="" style="color: rgb(79, 129, 135);">FunctionType</span><span class="Apple-converted-space"> </span><span class="" style="color: rgb(187, 44, 162);">where</span><span class="Apple-converted-space"> </span>Signature == (() -> Void) {</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> <span class="" style="color: rgb(187, 44, 162);">func</span><span class="Apple-converted-space"> </span>dispatchAsync(queue:<span class="Apple-converted-space"> </span><span class="" style="color: rgb(112, 61, 170);">dispatch_queue_t</span>) {</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> dispatch_async(queue,<span class="Apple-converted-space"> </span><span class="" style="color: rgb(187, 44, 162);">self</span>)</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"> }</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">}</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 <<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="">--<span class="Apple-converted-space"> </span><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=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a></div></blockquote></div></blockquote></div><br class=""></body></html>