> Vladimir.S via swift-evolution <swift-evolution@swift.org> 於 2017年6月9日 上午5:05 > 寫道: > > On 08.06.2017 21:17, Gwendal Roué via swift-evolution 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)) -> () >> leta = { (x: Int, y: Int) -> Intin... } >> letb = { ((x: Int, y: Int)) -> Intin... } >> 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: >> funcwantsTwoArguments(_closure: (Int, Int) -> Int) { closure(1, 2) } >> wantsTwoArguments{ a, b ina + b } >> wantsTwoArguments{ (a, b) ina + b } >> wantsTwoArguments{ t int.0+ t.1} // OK, maybe not >> funcwantsATupleArgument(_closure: ((Int, Int)) -> Int) { closure((1, 2)) } >> wantsATupleArgument{ a, b ina + b } >> wantsATupleArgument{ (a, b) ina + b } >> wantsATupleArgument{ t int.0+ t.1} >> funcwantsANamedTupleArgument(_closure: ((lhs: Int, rhs: Int)) -> Int) { >> closure((lhs: 1, rhs: 2)) } >> wantsANamedTupleArgument{ a, b ina + b } >> wantsANamedTupleArgument{ (a, b) ina + b } >> wantsANamedTupleArgument{ t int.lhs + t.rhs } > > It's nice to see that we are agreed that func/closures declared separately > should have clearly defined type and (at least for now) can't be > interchangeable. > > And personally I agree that this could be a solution to migration problem, > compiler can generate closure of correct(requested) type if such closure: > 1. declared inplace of func call as parameter of that func > 2. has no type annotations for its arguments > 3. (probably, can discuss) has no parenthesis for its arguments, because one > pair of parenthesis in argument list declares closure of type (list of > arguments)->T in other situations. > > So, we can have > > wantsTwoArguments{ a, b in a + b } // (Int,Int)->() will be generated > wantsTwoArguments{ (a, b) in a + b } // syntax of (Int,Int)->() closure > > wantsATupleArgument{ a, b in a + b } // ((Int,Int))->() will be generated > wantsATupleArgument{ t in t.0+ t.1 } // syntax of ((Int,Int))->() closure > > wantsANamedTupleArgument{ a, b in a + b } // ((Int,Int))->() will be generated > wantsANamedTupleArgument{ t in t.lhs + t.rhs } // syntax of ((Int,Int))->() > closure
That's what Swift 3 has done now, but forbidden by Swift 4. Isn't it? > So, { a,b in ...} will be a special syntax for closure which type will be > defined by compiler by type of func's parameter. > > The question is if community and core team will support this idea, if that > idea is better than other ideas like {((a,b)) in ..} for tuple > deconstruction, and if this could be implemented before Swift 4 release. > >> *This gives us the ability to deal with unfitted function signatures.* For >> example, most Dictionary methods. Yes, they are usually unfitted: >> extensionDictionary{ >> funcforEach(_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: >> letscores: [String: Int] = ... // [playerName: score] >> scores.forEach { name, score in >> print("\(name): \(score)") >> } >> Do you see? > > let scores: [String: Int] = ["a":1, "b":2] > > scores.forEach { (score: (name:String, value:Int)) in > print("\(score.name): \(score.value)") > } > > I'm not saying that this syntax as good as in your example, but it is not as > bad/ugly as you say. > >> 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 _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution