<div dir="ltr">This is an interesting proposal, but I think splatting like Python would be preferable: creators of functions use separate parameters and callers can expand tuples as necessary by prefixing a tuple at point of use with * to expand it into separate arguments. <div><br></div><div>Even with the Swift language as it is today, it looks like the right thing to do when you want named pieces of data is to define separate parameters (or fall back to using a tuple parameter with named components if that's really impossible).<div><br><div>Erica points out that you can do a lot with the current language. I did some experiments to see what's possible and it's really easy to enhance Swift to make it possible to pass tuples to functions expecting separate parameters. There are a couple of interesting ops that can go into a library to make things easier:</div></div><div>1. Anonymize a tuple</div><div>2. Wrap a function that takes separate arguments with one that takes a tuple</div><div><br></div><div>The downside to doing it in a library instead of the compiler is that you have to splat the function instead of the tuple.</div><div><br></div><div>If you have a function 'fn' that takes separate arguments and a tuple 't' that matches the arguments, you could call it like</div><div>(*fn)(t)</div><div>instead of</div><div>fn(*t)</div><div><br></div><div>That's not so bad if one tuple contains all the arguments</div><div><br></div><div>You can see experiments at</div><div><a href="https://gist.github.com/callionica/43f79dd0a9b145746d72e8a8a62c2820">https://gist.github.com/callionica/43f79dd0a9b145746d72e8a8a62c2820</a><br></div><div>and I will probably write something about this at</div></div><div><a href="http://www.callionica.com/developer/#swift-splat">http://www.callionica.com/developer/#swift-splat</a><br></div><div>at some point</div><div><br></div><div>-- Callionica</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, May 30, 2016 at 2:09 PM, Erica Sadun via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><span class=""><br><div><blockquote type="cite"><div>On May 30, 2016, at 2:39 PM, Chris Lattner via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br><div><div><blockquote type="cite">On May 30, 2016, at 6:01 AM, Brent Royal-Gordon via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:<br><br>// Proposed syntax:<br>func takes(a (valueA, valueB): (Int, Int)) {<br> // use valueA<br> // use valueB<br>}<br></blockquote><br>FWIW, Swift 1 supported tuple destructuring in parameter lists, and we took it out to simplify the language and eliminate special cases. Whereas as a very early version of swift modeled parameter lists using patterns (something very common in functional programming languages) we have progressively and intentionally move away from that approach.<br><br>-Chris<br></div></div></blockquote><br></div></span><div>You can't splat but you <i>can</i> decompose a tuple by assignment:</div><div><br></div><div><div style="margin:0px;font-size:16px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">let</span><span> a = (</span><span style="color:#272ad8">1</span><span>, </span><span style="color:#272ad8">2</span><span>, </span><span style="color:#272ad8">3</span><span>)</span></div><div style="margin:0px;font-size:16px;line-height:normal;font-family:Menlo"><span><span style="color:#bb2ca2">func</span> foo(v1: <span style="color:#703daa">Int</span>, v2: <span style="color:#703daa">Int</span>, v3: <span style="color:#703daa">Int</span>) { <span style="color:#3d1d81">print</span> (v1, v2, v3) }</span></div><div style="margin:0px;font-size:16px;line-height:normal;font-family:Menlo"><span><br></span></div><div style="margin:0px;font-size:16px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal;color:rgb(0,132,0)"><span>// Still works:</span></div><div style="margin:0px;line-height:normal"><span style="color:#bb2ca2">let</span><span> (b, c, d) = </span><span style="color:#4f8187">a</span><span>; </span><span style="color:#3d1d81">print</span><span>(</span><span style="color:#4f8187">b</span><span>, </span><span style="color:#4f8187">c</span><span>, </span><span style="color:#4f8187">d</span><span>)</span></div><div style="margin:0px;line-height:normal"><span><br></span></div><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal;color:rgb(0,132,0)"><span>// And this works after the assignment:</span></div><div style="margin:0px;line-height:normal"><span style="color:#31595d">foo</span><span>(v1: </span><span style="color:#4f8187">b</span><span>, v2: </span><span style="color:#4f8187">c</span><span>, v3: </span><span style="color:#4f8187">d</span><span>)</span></div><div><br></div></span></div></div><div style="margin:0px;font-size:16px;line-height:normal;font-family:Menlo"><div style="margin:0px;line-height:normal;color:rgb(0,132,0)"><span>// No longer works:</span></div><div style="margin:0px;line-height:normal;color:rgb(0,132,0)"><span style="color:#31595d">foo</span><span style="color:#000000">(</span><span style="color:#4f8187">a</span><span style="color:#000000">) </span><span>// tuple splat is gone</span></div><div style="margin:0px;line-height:normal;color:rgb(0,132,0)"><span><br></span></div><div style="margin:0px;line-height:normal;color:rgb(0,132,0)"><span><div style="margin:0px;line-height:normal"><span>// These all work though:</span></div><div style="margin:0px;line-height:normal"><span style="color:#bb2ca2">func</span><span> bar(arg: (</span><span style="color:#703daa">Int</span><span>, </span><span style="color:#703daa">Int</span><span>, </span><span style="color:#703daa">Int</span><span>)) { </span><span style="color:#3d1d81">print</span><span>(arg.</span><span style="color:#272ad8">0</span><span>, arg.</span><span style="color:#272ad8">1</span><span>, arg.</span><span style="color:#272ad8">2</span><span>) }</span></div><div style="margin:0px;line-height:normal"><span style="color:#31595d">bar</span><span>(arg: </span><span style="color:#4f8187">a</span><span>)</span></div><div style="margin:0px;line-height:normal"><span style="color:#31595d">bar</span><span>(arg: (</span><span style="color:#4f8187">b</span><span>, </span><span style="color:#4f8187">c</span><span>, </span><span style="color:#4f8187">d</span><span>))</span></div><div style="margin:0px;line-height:normal"><span><br></span></div><div style="margin:0px;line-height:normal"><span><div style="margin:0px;line-height:normal"><span>// You can add field names in the func's decl type</span></div><div style="margin:0px;line-height:normal"><span style="color:#bb2ca2">func</span><span> blort(arg: (x: </span><span style="color:#703daa">Int</span><span>, y: </span><span style="color:#703daa">Int</span><span>, z: </span><span style="color:#703daa">Int</span><span>)) { </span><span style="color:#3d1d81">print</span><span>(arg.x, arg.y, arg.z) }</span></div><div style="margin:0px;line-height:normal"><span style="color:#31595d">blort</span><span>(arg: </span><span style="color:#4f8187">a</span><span>) // works</span></div><div style="margin:0px;line-height:normal"><span style="color:#31595d">blort</span><span>(arg: (</span><span style="color:#4f8187">b</span><span>, </span><span style="color:#4f8187">c</span><span>, </span><span style="color:#4f8187">d</span><span>)) // works</span></div><div><br></div></span></div><div><div style="margin:0px;line-height:normal"><span>// But the following doesn't work, Error is "cannot </span></div><div style="margin:0px;line-height:normal"><span>// convert value of (l: Int, m: Int, n: Int)"</span></div><div style="margin:0px;line-height:normal"><span style="color:#31595d">blort</span><span>(arg: (l: </span><span style="color:#4f8187">b</span><span>, m: </span><span style="color:#4f8187">c</span><span>, n: </span><span style="color:#4f8187">d</span><span>))</span></div></div><div><br></div></span></div></div><div style="margin:0px;font-size:16px;line-height:normal;font-family:Menlo"><div style="font-family:Palatino;font-size:14px">I vaguely remember a discussion onlist about creating typealiases and then using casting to convert between structurally identical tuples but I don't think it went anywhere or had a strong use case.</div><span class="HOEnZb"><font color="#888888"><div style="font-family:Palatino;font-size:14px"><br></div><div style="font-family:Palatino;font-size:14px">-- E</div><div style="font-family:Palatino;font-size:14px"><br></div></font></span></div></div></div><br>_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br></blockquote></div><br></div>