<html><body><div><div style="color: #000000; font-family: SFNSText, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #ffffff; text-decoration-style: initial; text-decoration-color: initial;" data-mce-style="color: #000000; font-family: SFNSText, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #ffffff; text-decoration-style: initial; text-decoration-color: initial;">At first I thought that task 1 looked innocuous enough; then I discovered this bizarre behavior. Not sure if this was the point of your email.&nbsp;</div><div style="color: #000000; font-family: SFNSText, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #ffffff; text-decoration-style: initial; text-decoration-color: initial;" data-mce-style="color: #000000; font-family: SFNSText, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #ffffff; text-decoration-style: initial; text-decoration-color: initial;"><br></div><div style="color: #000000; font-family: SFNSText, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #ffffff; text-decoration-style: initial; text-decoration-color: initial;" data-mce-style="color: #000000; font-family: SFNSText, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #ffffff; text-decoration-style: initial; text-decoration-color: initial;"><div dir="ltr"><div dir="ltr"><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);">func compose&lt;T, U, V&gt;(_ g: @escaping (U)-&gt;V, _ f: @escaping (T)-&gt;U) -&gt; (T)-&gt;V {</span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);"><span class="gmail-Apple-tab-span"></span>return { x in g(f(x)) }</span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);">}</span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);"><br></span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);">func strung(_ tuple: (Int, Int)) -&gt; (String, String) {</span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);"><span class="gmail-Apple-tab-span"></span>return ("\(tuple.0)", "\(tuple.1)")</span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);">}</span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);"><br></span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);">func concat(_ tuple: (String, String)) -&gt; String {</span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);"><span class="gmail-Apple-tab-span"></span>return tuple.0 + tuple.1</span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);">}</span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);"><br></span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);">print(String(reflecting: compose(concat, strung)(3, 4))) // "34"; but shouldn't we need a tuple?</span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);">print(String(reflecting: compose(concat, strung)((3, 4)))) // "34"; this makes sense</span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);"><br></span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);">let f = compose(concat, strung)</span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);">print(String(reflecting: f(3, 4))) // ERROR: extra argument in call; but if the first line works, shouldn't this too?</span></span></div><div><span color="#000000" data-mce-style="color: #000000;" style="color: #000000;"><span style="background-color: rgba(255, 255, 255, 0);" data-mce-style="background-color: rgba(255, 255, 255, 0);">print(String(reflecting: f((3, 4)))) // "34"; also makes sense</span></span></div></div></div></div></div><div><br>On Jun 07, 2017, at 03:03 PM, Jens Persson via swift-evolution &lt;swift-evolution@swift.org&gt; wrote:<br><br></div><div><blockquote type="cite"><div class="msg-quote"><div dir="ltr"><div>Swift uses parentheses for a lot of different things (tuples, parameters, calls, grouping, pattern matching, etc), this has led to some confusion, for both language designers and users.<br></div><div><br></div><div>Here's a practical introduction that is possibly worth more than a thousand words (or perhaps even swift-evo posts):</div><div><br></div><div>&nbsp; Exercise 1</div><div>&nbsp; &nbsp; Write a (generic) function composition operator in Swift 4</div><div>&nbsp; &nbsp; (working as expected for all function types).</div><div><br></div><div>&nbsp; Exercise 2</div><div>&nbsp; &nbsp; Write a generic type WrappedFunction that can wrap any function in Swift 4</div><div>&nbsp; &nbsp; (with type parameters for Input and Output).</div><div><br></div><div>When you have completed (or given up) the exercises, please note that once in the history of Swift, these were simple tasks. You could come up with working solutions very quickly without any boilerplate or special casing (although perhaps not entirely without some of the parentheses-related inconsistencies of that time).</div><div><br></div><div>I've been reporting a lot of parentheses-related bugs since the first Swift beta, and I'm only getting more and more worried that the current incremental approach to fixing these is not working very well, resulting in a language that is more complex and less expressive than it could be.</div><div><br></div><div>Discussions often seem to end up being a bit too focused on particular use cases and details, and less on how everything fit together as a system.</div><div><br></div><div><br></div><div><div>So I wonder if any of you have had any thoughts about what Swift's parentheses-related&nbsp;future (or evolutionary baggage) will be?</div></div><div><br></div><div><br></div><div>PS</div><div><br></div><div><div>My perhaps unpopular thoughts:</div></div><div><br></div><div>I wish the parentheses-related parts of Swift could be carefully evaluated and redesigned from scratch, as a whole, in order to arrive at a solution that is as simple and expressive as possible.</div><div><br></div><div>But perhaps this has already happened and we are now just taking some steps back that are necessary for reimplementing some of the good stuff (that has been - at least IMHO - sort of hinted in earlier versions of Swift). But it feels like there is not enough time ...</div><div><br></div><div>Swift, please break my code all you want before it's too late, as long as it results in increased (rather than decreased) consistency, simplicity, expressiveness, optimizability and safety. Otherwise I could have used Objective C++.&nbsp;<br></div><div><br></div><div>/Jens</div><div><br></div></div><div class="_stretch"><span class="body-text-content">_______________________________________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" data-mce-href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" data-mce-href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></span></div></div></blockquote></div></body></html>