[swift-users] How to store ref to any kind of function, and call with it argument list?

C. Keith Ray keithray at mac.com
Fri Nov 3 21:01:19 CDT 2017


um... how can I cast functions taking one argument to a "generic function pointer" type?

typealias OneArgsFunction = (Any)->Any

func intToInt(_ i: Int) -> Int { return 4 }
func floatToFloat(_ f: Float) -> Float { return 0.4 }

var function : OneArgsFunction = intToInt
function = floatToFloat

error: f.playground:4:34: error: cannot convert value of type '(Int) -> Int' to specified type 'OneArgsFunction' (aka '(Any) -> Any')
var function : OneArgsFunction = intToInt
                                 ^~~~~~~~

error: f.playground:5:12: error: cannot assign value of type '(Float) -> Float' to type 'OneArgsFunction' (aka '(Any) -> Any')
function = floatToFloat
           ^~~~~~~~~~~~


--
C. Keith Ray
Senior Software Engineer / Trainer / Agile Coach
* http://www.thirdfoundationsw.com/keith_ray_resume_2014_long.pdf



> On Nov 3, 2017, at 2:24 PM, Slava Pestov <spestov at apple.com> wrote:
> 
> Unfortunately we don’t have a way to invoke a function with a runtime argument list because that would require runtime code generation in the most general case.
> 
> I would hack around it by handling the common cases of no arguments, 1 argument, 2 arguments, etc up to some fixed number of arguments that you consider “enough”. Use a switch on the type of the function.
> 
> Slava
> 
>> On Nov 3, 2017, at 2:21 PM, C. Keith Ray via swift-users <swift-users at swift.org <mailto:swift-users at swift.org>> wrote:
>> 
>> In the code below, I'm trying to store a reference to a function with any number of arguments, with any return type. And I want to be able to invoke it. 
>> 
>> Help?
>> 
>> See the comments with "*******"
>> 
>> typealias Void = ()
>> 
>> func equalTypes(_ me: [Any.Type], _ other: [Any.Type]) -> Bool {
>>     guard me.count == other.count else { return false }
>>     
>>     for i in 0 ..< me.count {
>>         if me[i] != other[i] { return false }
>>     }
>>     return true
>> }
>> 
>> struct Function {
>>     var returnType: Any.Type
>>     var argTypes: [Any.Type]
>>     var function: Any // ******* any function *******
>>     
>>     func perform(_ args: [Any]) -> Any {
>>         // ******* call function() with args, return result *******
>>         return 0
>>     }
>>     
>>     func isCompatible(_ other: Function) -> Bool {
>>         return self.returnType == other.returnType &&
>>             equalTypes(argTypes, other.argTypes)
>>     }
>> }
>> 
>> func vToV() {
>>     print("vToV")
>> }
>> 
>> func intToInt(_ i: Int) -> Int {
>>     print("intToInt")
>>     return 4
>> }
>> 
>> let f = Function(returnType: Void.self,
>>                  argTypes: [],
>>                  function: vToV)
>> let r = f.perform([])
>> print(r)
>> 
>> let f2 = Function(returnType: Int.self,
>>                  argTypes: [Int.self],
>>                  function: intToInt)
>> let r2 = f2.perform([12])
>> print(r2)
>> 
>> assert(f.isCompatible(f))
>> assert(!f.isCompatible(f2))
>> 
>> 
>> --
>> C. Keith Ray
>> Senior Software Engineer / Trainer / Agile Coach
>> * http://www.thirdfoundationsw.com/keith_ray_resume_2014_long.pdf <http://www.thirdfoundationsw.com/keith_ray_resume_2014_long.pdf>
>> 
>> 
>> 
>> _______________________________________________
>> swift-users mailing list
>> swift-users at swift.org <mailto:swift-users at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-users
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20171103/4a5f2dad/attachment.html>


More information about the swift-users mailing list