[Pitch #3] Introduce user-defined dynamically "callable" types

I suppose the proposal is not exactly clear on this:

 func dynamicCall(arguments: [T1]) -> T2
 func dynamicCall(keywordArguments: [(String, T3)]) -> T4
 func dynamicMethodCall(baseName: S1, arguments: [T5]) -> T6
 func dynamicMethodCall(baseName: S2, keywordArguments: [(S3, T7)]) -> T8

Can it be that T1 != T3, or T2 != T4? Or are these basically "Argument" and "Result" associated types (limited to 1 per conformer)? Otherwise you could create some weird stuff:

@dynamicCallable
struct RubyAndPython {

 func dynamicCall(arguments: [PyVal]) -> PyVal { ... }

 func dynamicMethodCall(baseName: String, arguments: [RubyVal]) -> RubyVal { ... }
}

There is a mistake in the proposal where it says:

Python does support keyword arguments. While it could just implement that hook, where we implement the keyword and non-keyword forms to avoid allocating a temporary dictionary in the non-keyword case:

There are no dictionaries in this proposal. Keyword arguments are passed as an array of tuples.


Also, how are you going to call this function with an Int or String without explicitly boxing them as PyVals? You would need T1 to be a protocol (PythonConvertible or something).

As it happens, there was some talk about allowing protocols to satisfy associated-types, exactly for these kind of architectures. [Pitch] Generalized supertype constraints

EDIT: Indeed, this is what the Playground does: https://github.com/google/swift/blob/a988b64966b1830cd379419e401d11efdca092d1/stdlib/public/Python/Python.swift#L272