Hi Everyone,
I'm having trouble using a generic function
func genericCall<T, Args, Ret>(_ closure: (T) -> (Args) -> Ret,
_ t: T,
_ args: Args) -> Ret {
return closure(t)(args)
}
class Test {
func sum(a:Int, b:Int) -> Int { return a + b }
func pr(a:Int) { print(a) }
}
let t = Test()
genericCall(Test.sum, t, (2, 4)) // error
genericCall(Test.pr, t, (1)) // no problem
When the method has more than 1 parameter the compiler err's with 'Cannot convert type (Test)->(Int,Int)-> Int to expected type (_)->(_)->()'
Is this a bug or I'm missing something here? (using Xcode 10.1 (10B61))
Thanks
SDGGiesbrecht
(Jeremy David Giesbrecht)
2
Argument lists and tuples are not implicitly interchangeable. You are trying to send a single (2, 4) tuple to a function that requires two separate arguments.
You will need to duplicate genericCall for each number of arguments you want to use it with. This would be the two‐argument variant:
func genericCall<T, Arg1, Arg2, Ret>(_ closure: (T) -> (Arg1, Arg2) -> Ret,
_ t: T,
_ args: (Arg1, Arg2)) -> Ret {
return closure(t)(args.0, args.1)
}
DRehren
3
Thanks, I've read about Tuple Splat and though that it was still on the language, but forgot that it is removed.
1 Like
From the end of SE-0029:
The major problem with this feature is that it was not well considered and implemented properly [...]. As such, the alternative is to actually design a proper feature to support this. [...] If there is serious interest in pursuing this as a concept, we should do it as a follow-on proposal to this one. If a good design emerges, we can evaluate that design based on its merits.
Do you have any thoughts on the matter other than wishing you could still use it?
I was just wishing to use it.. but your question made me think about it...
Having it could lead to some interesting APIs to pop up (like something I was doing, in having an extension of an object to be able to call into a method of another without much roundtrips).
For this to happen I think a good place to start is to attribute the closure/func/method of being able to receive it's parameters in a tuple, like
@mergableparams func mayTupledArgsFunc(_ a: Int, _ b: String) { }
...
mayTupledArgsFunc(42, "Hello World!") // or..
let args = (42, "Hello World!")
mayTupledArgsFunc(args)
But as previously said, it's a sugar feature and also I found a "workaround" already.
It was just that I was thinking in a maybe less verbose way to do it (although I didn't like much the use of the tuple in genericCall anyway...)