[swift-evolution] Proposal: Always flatten the single element tuple

Adrian Zubarev adrian.zubarev at devandartist.com
Wed Jun 7 05:54:04 CDT 2017


Answer inlined:
Am 7. Juni 2017 um 12:33:51, Gwendal Roué (gwendal.roue at gmail.com) schrieb:


Le 7 juin 2017 à 12:03, Adrian Zubarev via swift-evolution <swift-evolution at swift.org> a écrit :

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 }


Despite Chris Lattern being a semi-god, his double-parenthesis suggestion cruelly lacks in terms of user ergonomics. 
Well it’s clearly not the ideal solution from a visual perspective but it’s an unambiguous one. If tuples were represented differently, let’s say `@(a, b)` we wouldn’t sit here and debate that long because it becomes crystal clear what should be possible and what not.



The compiler should be able to deal with the following code snippet, just like Swift 3 does:

    // two arguments
    func f1(_ closure: (Int, Int) -> Int) { closure(1, 2) }
    f1 { lhs, rhs in lhs + rhs }
    f1 { (lhs, rhs) in lhs + rhs }
Next one is a bug to me:


    f1 { tuple in tuple.0 + tuple.1 }
Fine:


    f1(+)
    
    // two arguments, with documentation names
    func f2(_ closure: (_ a: Int, _ b: Int) -> Int) { closure(1, 2) }
    f2 { lhs, rhs in lhs + rhs }
    f2 { (lhs, rhs) in lhs + rhs }
Another bug to me:


    f2 { tuple in tuple.0 + tuple.1 }
Fine:


    f2(+)
    
    // one tuple argument
    func f3(_ closure: ((Int, Int)) -> Int) { closure((1, 2)) }
Should be `((lhs, rhs)) in` which eliminates both of the next two scenarios completely:


    f3 { lhs, rhs in lhs + rhs }
    f3 { (lhs, rhs) in lhs + rhs }
Fine:


    f3 { tuple in tuple.0 + tuple.1 }
Should be an error:


    f3(+)
See `f3`


    
    // one keyed tuple argument
    func f4(_ closure: ((a: Int, b: Int)) -> Int) { closure((a: 1, b: 2)) }
    f4 { lhs, rhs in lhs + rhs }
    f4 { (lhs, rhs) in lhs + rhs }
    f4 { tuple in tuple.a + tuple.b }
    f4(+)

This covers the Swift 3 regressions developped by Stephen Celis and I, unless I have missed any. And this should be the goal of the designers of this language, *regardless of the actual types*. Developers are olding their breath: please just make this happen.

Now Swift 3 may have an issue with $n parameters. Here is my suggestion, should `((Int, Int)) -> Int` be different from `(Int, Int) -> Int`:


That’s what I would expect.

    f1 { $0 + $1 } // OK
    f1 { $0.0 + $0.1 } // OK in Swift 3, compiler error in Swift 4?
    
    f2 { $0 + $1 } // OK
    f2 { $0.0 + $0.1 } // OK in Swift 3, compiler error in Swift 4?
    
    f3 { $0 + $1 } // OK in Swift 3, compiler error in Swift 4?
    f3 { $0.0 + $0.1 } // OK
    
    f4 { $0 + $1 } // OK in Swift 3, compiler error in Swift 4?
    f4 { $0.a + $0.b } // OK

Gwendal Roué


These rules should as strict as they possible can be now. Later on we can add sugar to relax some of them. Here is a quote, again from Chris Lattner:

The art of evolving Swift forward is to carefully pick and choose areas to focus on, both because we want to ensure a coherent language, but also because implementor bandwidth is limited.

Beyond that, though syntactic sugar is always motivated by strong rationale and use-cases, in my opinion, it is the most dangerous kind of additive feature to consider at this point of Swift’s evolution. While these features are useful, they also clearly add complexity to the language, and it is difficult to gauge whether the problem being addressed will even exist in Swift as the other bigger features come in (for example, a macro system). These features can also make future language evolution more problematic because they consume syntactic real estate in the language.

If you’re into analogies, I see features like the generics improvements, ownership model, concurrency model, macro system, new frameworks, and other large scale efforts as the “bricks" that make up the house of Swift. In that analogy, syntactic sugar proposals are “mortar” that fills in the cracks between the bricks. If we add too much mortar too early on, we run the risk of the house of Swift being built out of mortar, or of not being able to fit the bricks into the right places. That would be very bad, given that we all want the house of Swift to be strong and beautiful over the long term.

-Chris 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170607/af77a3be/attachment.html>


More information about the swift-evolution mailing list