Update: the callable WIP branch is available at Introduce callables. by dan-zheng · Pull Request #23517 · apple/swift · GitHub.
The major change is the addition of the new call
declaration kind, as described in this pitch.
Parsing is nearly done, sans an unideal parsing diagnostic to fix.
-
call
is a keyword only in declaration-parsing contexts sofunc call(...)
andcall(...)
apply expression are still valid. -
Added parsing source compatibility tests, here's an excerpt:
// Test context sensitive parsing. // "call" can appear in declaration or expression contexts. struct ContextSensitiveParsing { // declaration call(_ fn: () -> Void) { // expression call() {} // expression call {} struct U { // declaration call(x: Int) {} // error // expected-error @+1 {{expected '(' for 'call' member parameters}} {{11-11=()}} call {} } } } // Global function. Used below. func call(_ fn: () -> Void) {} // expression call() {}
Type-checking needs a bit more work needs a bit more work, namely "looking up all call
declarations" in a robust way. This means call
declarations don't quite work as protocol requirements yet, but this will be fixed soon.
These examples work though:
struct SimpleCallable {
call(_ x: Float) -> Float {
return x
}
}
let foo = SimpleCallable()
_ = foo(1)
_ = foo(foo(1))
// Test direct references.
_ = foo.call(1)
_ = [1, 2, 3].map(foo.call)
_ = foo.call(foo(1))
_ = foo(foo.call(1))
let _: (Float) -> Float = foo.call
// Generics work too.
struct Generic {
call<T, U>(_ x: T, _ y: U) -> (T, U) {
return (x, y)
}
}
let generic = Generic()
_ = generic(1, 3.0)
_ = generic(generic, generic.call as ([Int], Float) -> ([Int], Float))
Feel free to take a look if you're interested - feedback appreciated!