> Le 8 juin 2017 à 19:40, Brent Royal-Gordon via swift-evolution > <swift-evolution@swift.org> a écrit : > >> On Jun 7, 2017, at 3:03 AM, Adrian Zubarev via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >> Well please no: >> >> >> let fn2: ((Int, Int)) -> Void = { lhs, rhs in } >> >> Instead use destructuring sugar pitched by Chris Lattner on the other thread: >> >> let fn2: ((Int, Int)) -> Void = { ((lhs, rhs)) in } >> > > I think this suggestion is better than the status quo. I'm wondering, though, > if we should just drop the outer set of parentheses entirely, unless you're > also putting types on the parameters. That is, a closure of type `(Int, Int) > -> T` can look like this: > > { (x: Int, y: Int) in … } > > Or it can look like this: > > { x, y in … } > > But it *cannot* look like this: > > { (x, y) in … } > > The `(x, y)` form can instead be a closure of a type like `((Int, Int)) -> > T`, which immediately destructures the tuple parameter into separate > constants. > > -- > Brent Royal-Gordon > Architechies
Hello, There's a difference, in the mind of people here that try to show how bad were the recent changes, between: 1: closures defined independently 2: closures given as a parameter to a function. I think that we all agree that the type of a closure that is defined independently should be well defined: // Choose between (Int, Int) -> () or ((x: Int, y: Int)) -> () let a = { (x: Int, y: Int) -> Int in ... } let b = { ((x: Int, y: Int)) -> Int in ... } However, when a closure is given as an argument of a function that expects a closure, we ask for the maximum possible flexibility, as Swift 3 did: func wantsTwoArguments(_ closure: (Int, Int) -> Int) { closure(1, 2) } wantsTwoArguments { a, b in a + b } wantsTwoArguments { (a, b) in a + b } wantsTwoArguments { t in t.0 + t.1 } // OK, maybe not func wantsATupleArgument(_ closure: ((Int, Int)) -> Int) { closure((1, 2)) } wantsATupleArgument { a, b in a + b } wantsATupleArgument { (a, b) in a + b } wantsATupleArgument { t in t.0 + t.1 } func wantsANamedTupleArgument(_ closure: ((lhs: Int, rhs: Int)) -> Int) { closure((lhs: 1, rhs: 2)) } wantsANamedTupleArgument { a, b in a + b } wantsANamedTupleArgument { (a, b) in a + b } wantsANamedTupleArgument { t in t.lhs + t.rhs } This gives us the ability to deal with unfitted function signatures. For example, most Dictionary methods. Yes, they are usually unfitted: extension Dictionary { func forEach(_ body: ((key: Key, value: Value)) throws -> Void) rethrows } Who cares about this named (key:value:) tuple? Absolutely nobody, as exemplified by this remarquable Swift 3 snippet below, where no tuple, no `key`, and no `value` is in sight: let scores: [String: Int] = ... // [playerName: score] scores.forEach { name, score in print("\(name): \(score)") } Do you see? Gwendal
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution