On 29.05.2017 21:08, Nevin Brackett-Rozinsky wrote:
Vladimir, using your function definitions I would like to have:

// Two parameters:
barParams{ t in }       // invalid, too few parameters
barParams{ (t) in }     // invalid, too few parameters
barParams{ x, y in }    // valid, two parameters
barParams{ (x, y) in }  // valid, two parameters with optional parentheses
barParams{ ((x, y)) in }// invalid, too few parameters

OK, the same as I suggest.


// One parameter which is a 2-tuple:
barTuple{ t in }        // valid, one tuple parameter
barTuple{ (t) in }      // valid, one tuple parameter with optional parentheses
barTuple{ x, y in }     // invalid, too many parameters

OK..

barTuple{ (x, y) in }   // valid, destructuring one tuple
barTuple{ ((x, y)) in } // valid, destructuring one tuple with optional 
parentheses

Here is the problem for me. According to SE-0066 closure declared as {(x,y) in} should be of type (Int,Int)->() and not ((Int,Int))->().
Why do you want to be able to pass wrong function/closure type into barTuple?

For completeness: if a closure takes *any number* of parameters, it should be legal to list one identifier per parameter, separated by commas, with optionally a pair of parentheses surrounding that list. Furthermore, if *any* parameter is a tuple, it should be possible to replace the identifier corresponding to that parameter with a pair of parentheses containing a number of identifiers (separated by commas) equal to the arity of the tuple. And this tuple-destructuring should work recursively, so if a tuple contains a tuple [contains a tuple…] the inner tuples may optionally be destructured as well.

Well.. Theoretically I don't see any problem with this in suggested "double pair of parentheses" syntax:

typealias MyTuple = (Int, (String, (Double, Bool)))

func doSomething(callback: ((Int, Int), MyTuple)->()) {}

doSomething {point, mytuple in }
doSomething {((x,y)), mytuple in }
doSomething {((x,y)), ((i, sdb)) in }
doSomething {point, ((i, ((s, ((d, b)))))) in }

//probably even just that flat syntax if all values are destructured
doSomething {((x, y)), ((i, s, d, b)) in }

doSomething {(t, myt) in } // here we see that there are 2 arguments, not tuples
doSomething {(((x,y)), myt) in }
doSomething {(((x,y)), ((i, tuple))) in }
doSomething {(point, ((i, ((s, ((d, b))))))) in }

the double parentheses in closure argument declaration clearly shows that this is a tuple deconstruction.

The question if we'll decide to allow such feature(extended ability for tuple deconstructing in closure arguments).


To be clear: each tuple being destructured must have a pair of parentheses containing the identifiers it is being destructured into. It is only the very outermost parentheses around the entire parameter list of the closure which should be optional.


I see your position, but as I said, IMO single pair of parentheses is very ambiguous if it is a list of arguments or tuple deconstruction and we shouldn't disallow single pair of parentheses to surround a simple list of closure arguments in declaration.

Nevin



On Mon, May 29, 2017 at 1:32 PM, Vladimir.S <[email protected] <mailto:[email protected]>> wrote:

    On 29.05.2017 18:26, Nevin Brackett-Rozinsky via swift-evolution wrote:

        On Sun, May 28, 2017 at 7:04 PM, John McCall via swift-evolution
        <[email protected] <mailto:[email protected]>
        <mailto:[email protected] <mailto:[email protected]>>> 
wrote:


             We need to add back tuple destructuring in closure parameter lists
        because this
             is a serious usability regression.  If we're reluctant to just "do 
the right
             thing" to handle the ambiguity of (a,b), we should at least allow 
it via
             unambiguous syntax like ((a,b)).  I do think that we should just 
"do the
        right
             thing", however, with my biggest concern being whether there's any
        reasonable way
             to achieve that in 4.0.

             John.


        I agree with John, the best thing for actually using Swift is to allow 
tuple
        destructuring here, and the outermost parentheses (around the entire
        parameter list of a closure) should continue to be optional. Requiring
        double-parens would seem unnecessarily and arbitrarily…whatever the 
opposite
        of “convenient” is.

        Nevin


    If I understand correctly, correct me if I'm wrong, after *full* 
implementation
    of SE-0066, the function with two parameters should have different type than
    function with one tuple parameter:

    I.e.
    typealias FuncParams = (Int, Int)->()
    typealias FuncTuple = ((Int, Int))->()

    print(FuncParams.self) // should be (Int, Int)->()
    print(FuncTuple.self) // should be ((Int, Int))->()

    So, if we have

    func barParams(_ f: FuncParams) {
             f(1,2)
    }

    func barTuple(_ f: FuncTuple) {
             f((1,2))
    }

    and

    func fooWithParams(_ x: Int,  _ y: Int) {  }
    func fooWithTuple(_ tuple: (Int, Int)) {  }

    .. we should not be able to call

    barParams(fooWithTuple) // should be error: incompatible types
    barTuple(fooWithParams) // should be error: incompatible types


    If so, are you suggesting that this code should still be valid?

    barParams({tuple in}) // ?
    barTuple({x,y in}) // ?


    Will {x,y in} closure has ((Int, Int))->() type in this case?
    And if {tuple in} should be of type (Int,Int)->() ?

    If I'm not missing something, the only reasonable solution here is follow 
the
    SE-0066 rules for function types and allow special syntax ((x,y)) to 
deconstruct
    tuple parts in closure argument list, and such closure will have type
    ((Int,Int))->() as expected. So we'll have:

    barTuple({((x,y)) in ... })





        _______________________________________________
        swift-evolution mailing list
        [email protected] <mailto:[email protected]>
        https://lists.swift.org/mailman/listinfo/swift-evolution
        <https://lists.swift.org/mailman/listinfo/swift-evolution>


_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to