> On 8 Jun 2017, at 11:17, Gwendal Roué via swift-evolution > <swift-evolution@swift.org> wrote: > > >> Le 8 juin 2017 à 19:40, Brent Royal-Gordon via swift-evolution >> <swift-evolution@swift.org <mailto: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?
This post is the one that makes most sense to me! Be strict on definition but flexible on use. > Gwendal > > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution