> 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

Reply via email to