Hello Swift community,
Swift 3’s SE-0110
<https://github.com/apple/swift-evolution/blob/master/proposals/0110-distingish-single-tuple-arg.md>
eliminated the equivalence between function types that accept a single type
and function types that take multiple arguments. However, for various
implementation reasons
<https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170612/037560.html>,
the implementation of SE-0110 (as well as the elimination of tuple “splat”
behavior in SE-0029
<https://github.com/apple/swift-evolution/blob/master/proposals/0029-remove-implicit-tuple-splat.md>)
was not fully completed.
Swift 4 implemented more of SE-0110, which caused a fairly serious usability
regression, particularly with closures. Here are a few simple examples
involving closures that worked in Swift 3 but do not work in Swift 4:
// #1: Works in Swift 3, error in Swift 4
myDictionary.forEach {
print("\($0) -> \($1)")
}
// #2: Works in Swift 3, error in Swift 4
myDictionary.forEach { key, value in
print("\(key) -> \(value)")
}
// #3: Works in Swift 3, error in Swift 4
myDictionary.forEach { (key, value) in
print("\(key) -> \(value)")
}
Similar issues occur with passing multi-argument functions where a tuple
argument is expected:
// #4: Works in Swift 3, error in Swift 4
_ = zip(array1, array2).map(+)
In all of these cases, it is possible to write a closure that achieves the
desired effect, but the result is more verbose and less intuitive:
// Works in both Swift 3 and Swift 4
myDictionary.forEach { element in
let (key, value) = element
print("\(key) -> \(value)")
}
The Swift core team feels that these usability regressions are unacceptable for
Swift 4. There are a number of promising solutions that would provide a better
model for closures and address the usability regression, but fully designing
and implementing those are out of scope for Swift 4. Therefore, we will “back
out” the SE-0110 change regarding function arguments from Swift 4.
Specifically, when passing an argument value of function type (including
closures) to a parameter of function type, a multi-parameter argument function
can be passed to a parameter whose function type accepts a single tuple (whose
tuple elements match the parameter types of the argument function). Practically
speaking, all of the examples #1-#4 will be accepted in both Swift 3 and Swift
4.
We will revisit the design in this area post-Swift 4.
- Doug
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution