<div dir="ltr">Vladimir, using your function definitions I would like to have:<div><br></div><div><font face="monospace, monospace">// Two parameters:</font></div><div><div><span style="font-family:monospace,monospace">barParams{ t in }       <font color="#cc0000">// invalid, </font></span><font color="#cc0000"><span style="font-family:monospace,monospace">too few</span><span style="font-family:monospace,monospace"> parameters</span></font></div><div><span style="font-family:monospace,monospace"></span><font face="monospace, monospace">barParams{ (t) in }     <font color="#cc0000">// invalid, too few parameters</font></font></div></div><div><span style="font-family:monospace,monospace">barParams{ x, y in }    <font color="#38761d">// valid, two parameters</font></span><br></div><div><span style="font-family:monospace,monospace"></span><font face="monospace, monospace">barParams{ (x, y) in }  <font color="#38761d">// valid, two parameters with optional parentheses</font></font></div><div><span style="font-family:monospace,monospace">barParams{ ((x, y)) in }<font color="#cc0000">// invalid, </font></span><font color="#cc0000"><span style="font-family:monospace,monospace">too few</span><span style="font-family:monospace,monospace"> parameters</span></font></div><div><span style="font-family:monospace,monospace"><br></span></div><div><span style="font-family:monospace,monospace">// One parameter which is a 2-tuple:</span></div><div><div><span style="font-family:monospace,monospace">barTuple{ t in }        <font color="#38761d">// valid, one tuple parameter</font></span><br></div></div><div><div><span style="font-family:monospace,monospace">barTuple</span><span style="font-family:monospace,monospace">{ (t) in }      <font color="#38761d">// valid, one tuple parameter with optional parentheses</font></span></div><div><span style="font-family:monospace,monospace"></span><span style="font-family:monospace,monospace">barTuple{ x, y in }     <font color="#cc0000">// invalid, too many parameters</font></span><br></div><div><span style="font-family:monospace,monospace"></span><font face="monospace, monospace">barTuple{ (x, y) in }   <font color="#38761d">// valid, </font></font><font color="#38761d"><span style="font-family:monospace,monospace">destructuring one </span><font face="monospace, monospace">tuple</font></font></div><div><span style="font-family:monospace,monospace">barTuple</span><span style="font-family:monospace,monospace">{ ((x, y)) in } <font color="#38761d">// valid, destructuring one tuple with optional parentheses</font></span><span style="font-family:monospace,monospace"><br></span></div><div><br></div></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>Nevin</div><div><br></div><div><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, May 29, 2017 at 1:32 PM, Vladimir.S <span dir="ltr">&lt;<a href="mailto:svabox@gmail.com" target="_blank">svabox@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 29.05.2017 18:26, Nevin Brackett-Rozinsky via swift-evolution wrote:<span class=""><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
On Sun, May 28, 2017 at 7:04 PM, John McCall via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a> &lt;mailto:<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.<wbr>org</a>&gt;&gt; wrote:<br>
<br>
<br>
    We need to add back tuple destructuring in closure parameter lists because this<br>
    is a serious usability regression.  If we&#39;re reluctant to just &quot;do the right<br>
    thing&quot; to handle the ambiguity of (a,b), we should at least allow it via<br>
    unambiguous syntax like ((a,b)).  I do think that we should just &quot;do the right<br>
    thing&quot;, however, with my biggest concern being whether there&#39;s any reasonable way<br>
    to achieve that in 4.0.<br>
<br>
    John.<br>
<br>
<br>
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.<br>
<br>
Nevin<br>
</blockquote>
<br></span>
If I understand correctly, correct me if I&#39;m wrong, after *full* implementation of SE-0066, the function with two parameters should have different type than function with one tuple parameter:<br>
<br>
I.e.<br>
typealias FuncParams = (Int, Int)-&gt;()<br>
typealias FuncTuple = ((Int, Int))-&gt;()<br>
<br>
print(FuncParams.self) // should be (Int, Int)-&gt;()<br>
print(FuncTuple.self) // should be ((Int, Int))-&gt;()<br>
<br>
So, if we have<br>
<br>
func barParams(_ f: FuncParams) {<br>
        f(1,2)<br>
}<br>
<br>
func barTuple(_ f: FuncTuple) {<br>
        f((1,2))<br>
}<br>
<br>
and<br>
<br>
func fooWithParams(_ x: Int,  _ y: Int) {  }<br>
func fooWithTuple(_ tuple: (Int, Int)) {  }<br>
<br>
.. we should not be able to call<br>
<br>
barParams(fooWithTuple) // should be error: incompatible types<br>
barTuple(fooWithParams) // should be error: incompatible types<br>
<br>
<br>
If so, are you suggesting that this code should still be valid?<br>
<br>
barParams({tuple in}) // ?<br>
barTuple({x,y in}) // ?<br>
<br>
<br>
Will {x,y in} closure has ((Int, Int))-&gt;() type in this case?<br>
And if {tuple in} should be of type (Int,Int)-&gt;() ?<br>
<br>
If I&#39;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))-&gt;() as expected. So we&#39;ll have:<br>
<br>
barTuple({((x,y)) in ... })<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailma<wbr>n/listinfo/swift-evolution</a><br>
<br>
</blockquote>
</div></div></blockquote></div><br></div></div>