I ran into a weird tuple destructuring problem in Swift 5.2. I thought tuple destructuring didn't work inside a closure parameter since some time ago. And indeed, the following does not work:
let expected: ((Int, Int)) -> Void = { a, b in // does not compile
print(a, b)
}
However, I noticed that all of the below work:
func weird(closure: @escaping ((Int, Int)) -> Void) {
closure((1, 3))
}
// I can understand this
weird { print($0.0 + $0.1) }
weird { a, b in print(a + b) }
// Surprise!
weird { print($0 + $1) }
weird { p in print(p.0 + p.1) }
Did the last two examples worked before Swift 5.2? Is this behavior documented somewhere?
It is related to this proposal, which was once accepted in Swift 4.0.
SE-0110 Distinguish between single-tuple and multiple-argument function types
So, two of your examples (not last two though) caused error in a certain version of Swift, but Swift team found some unacceptable regression in this implementation. Additional Commentary
And since a certain version of Swift (I do not remember the exact version, it might have been 4.0.x or 4.1), you can pass two argument closure to the parameter of function type taking a single tuple.
And recently, this exception is confirmed to be a part of SE-0110 and if some more modification is needed, a new proposal will be made and go through the usual Swift Evolution process.
the original proposal as reviewed did not include the special-case conversion from
(T, U, ...) -> V
to((T, U, ...)) -> V
for function arguments. In response to community feedback, this conversion was added as part of the Core Team's acceptance of the proposal.
The Swift book may not have clear explanation of this behavior, but it surely is documented.