[swift-evolution] Splat

Alex Hoppen alex at ateamer.de
Thu Feb 11 09:36:16 CST 2016


> On 11 Feb 2016, at 16:05, Matthew Johnson <matthew at anandabits.com> wrote:
> 
>> 
>> On Feb 11, 2016, at 8:00 AM, Alex Hoppen via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>> 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).
>> 
>> So this protocol would look like
>> 
>> protocol FunctionSignatureType {
>>   associatedtype Parameters
>>   associatedtype ReturnType
>> }
>> 
>> Parameters will be set to the functions parameters in tuple notation
>> 
>> (((Int, String), secondParameter: Int) -> String).Input == ((Int, String), secondParameter: Int)
>> 
>> FunctionType would then only have one associated type:
>> 
>> protocol FunctionType {
>>   associatedtype Signature: FunctionSignatureType
>> }
>> 
>> Signature could for example be ((Int, String), secondParameter: Int) -> String.
>> 
>> We could then declare the apply function as a simple extension to FunctionType just like you suggested
>> 
>> extension FunctionType {
>>   func apply(tuple: Signature.Parameters) -> Signature.ReturnType {
>>     // Add some compiler magic here
>>   }
>> }
> 
> 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.  
> 

Good point, it seems like I haven’t completely considered other types conforming to FunctionType. 
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:
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
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.

>> 
>> 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:
>> 
>> extension FunctionType where Signature == (() -> Void) {
>>   func dispatchAsync(queue: dispatch_queue_t) {
>>     dispatch_async(queue, self)
>>   }
>> }
>> 
>> 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.
>> 
>> - Alex
>> 
>> 
>>> On 11 Feb 2016, at 08:54, Brent Royal-Gordon via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>> 
>>>> 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?
>>> 
>>> 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:
>>> 
>>> 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:
>>> 
>>> 	protocol Applicable {
>>> 		typealias ReturnValue
>>> 		typealias ArgumentTuple
>>> 		func apply(to: ArgumentTuple) -> ReturnValue
>>> 	}
>>> 
>>> (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.)
>>> 
>>> 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.
>>> 
>>> 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.)
>>> 
>>> 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.
>>> 
>>> -- 
>>> Brent Royal-Gordon
>>> Architechies
>>> 
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160211/c83a1a78/attachment.html>


More information about the swift-evolution mailing list