<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><br></div><div><br>On Jun 9, 2017, at 2:10 PM, Jens Persson via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><div dir="ltr">The point of exercise 1 is to show that it is impossible (in Swift 4) to write a generic function composition operator (or function) which works as expected for any reasonable functions.<div>This was possible in Swift 3, but in Swift 4 it will only work for functions with exactly one parameter. You'd have to special-case it for every combination of parameter counts of f and g that it should be able to handle.<br><div><br></div><div><div>The following program demonstrates how it can be done in Swift 3.1 and 3.2:</div><div><br></div><div>func compose&lt;T, U, V&gt;(_ g: @escaping (U) -&gt; V, _ f: @escaping (T) -&gt; U) -&gt; (T) -&gt; V {</div><div>&nbsp; &nbsp; return { x in g(f(x)) }<br></div><div>}</div><div>func sum(_ a: Int, _ b: Int) -&gt; Int { return a + b }</div><div>func square(_ a: Int) -&gt; Int { return a * a }</div><div>let squaredSum = compose(square, sum)</div><div>let result = squaredSum((3, 4)) // A bit unexepected with a tuple here but ok ...</div><div>print(result) // 49</div><div>// Well, it worked, not flawlessly but we did manage to write</div><div>// a function composition function and we composed sum</div><div>// and square, and we could call it and get a correct result.</div><div><br></div><div>&nbsp;</div><div>And this program demonstrates what happens if you try it in Swift 4:</div><div><br></div><div>func compose&lt;T, U, V&gt;(_ g: @escaping (U) -&gt; V, _ f: @escaping (T) -&gt; U) -&gt; (T) -&gt; V {</div><div>&nbsp; &nbsp; return { x in g(f(x)) }</div><div>}</div><div>func sum(_ a: Int, _ b: Int) -&gt; Int { return a + b }</div><div>func square(_ a: Int) -&gt; Int { return a * a }</div><div>// let squaredSum = compose(square, sum) // Error! (without the compose-variant below)</div><div><br></div><div>// The error message is:</div><div>// Cannot convert value of type `(Int, Int) -&gt; Int` to</div><div>// expected argument type `(_) -&gt; _`</div><div><br></div><div>// That's it, it is simply not possible!</div><div><br></div><div>// You'd have to write special variants of the compose func for every combination</div><div>// of parameter counts! For example, in order to get this sum and square</div><div>// example working, this specific variant must be written:</div><div>func compose&lt;T, U, V, W&gt;(_ g: @escaping (V) -&gt; W, _ f: @escaping (T, U) -&gt; V) -&gt; (T, U) -&gt; W {</div><div>&nbsp; &nbsp; return { (x, y) in g(f(x, y)) }</div><div>}</div><div>// Now it will work:</div><div>let squaredSum = compose(square, sum)</div><div>// But only thanks to that awfully specific compose func variant ...</div></div><div>// We would have to write a lot more variants for it to be practically usable on pretty much any common function.</div><div><br></div><div>I'm sure some will say:</div><div>"no regular developers use function composition anyway so why ..."</div><div>or</div><div>"It's not very swifty to use free functions and higher order functions like that."</div><div><br></div><div>My answer is that this is just a simple but telling example. The issue (as I see it) exists in all situations involving generics and function types.</div><div><br></div><div>I'm a regular programmer and I like to be able to write basic, useful abstractions.</div><div>It's no fun when the language forces you to write lots of specific variants of your generic code.</div><div><br></div><div>I would feel less worried about the parentheses situation if the language was going in a direction where you could see how this simple exercise would be a no brainer.</div><div><br></div><div>Can Swift's parentheses-situation be sorted out before ABI stability?</div><div>Otherwise it would be a bit like if Swift had kept the special rule for the first parameter, only much worse.</div><div><br></div></div></div></div></blockquote><div><br></div><div>Out of curiosity, how do you think this would impact ABI? What are your concrete concerns here?</div><div><br></div><div>I don't think the analogy of first parameter label is relevant, as that needn't be ABI.&nbsp;</div><br><blockquote type="cite"><div><div dir="ltr"><div><div>/Jens</div><div><br></div><div><br></div><div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jun 9, 2017 at 7:17 PM, Gor Gyolchanyan <span dir="ltr">&lt;<a href="mailto:gor@gyolchanyan.com" target="_blank">gor@gyolchanyan.com</a>&gt;</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;line-break:after-white-space">Yes, except why would you need to define `((A, B)) -&gt; C`?, If you need to pass a 2-element tuple into a function that takes two parameters - you can! If you want to pass two values into a function that &nbsp;*looks* like it takes a single 2-element tuple - you can! Seems to me that the difference between `((A, B)) -&gt; C` and `(A, B) -&gt; C` is virtually non-existent. But keep in mind that this only works for bare tuples (the ones that can't have labels). Non-closure functions DO have labels, which is part of their signature, so this is a different story.<div><div class="h5"><div><div><br><blockquote type="cite"><div>On Jun 9, 2017, at 6:18 PM, Gwendal Roué &lt;<a href="mailto:gwendal.roue@gmail.com" target="_blank">gwendal.roue@gmail.com</a>&gt; wrote:</div><br class="m_-5030093235766988749Apple-interchange-newline"><div><div style="word-wrap:break-word"><br><div><blockquote type="cite"><div>Le 9 juin 2017 à 17:12, Gor Gyolchanyan via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; a écrit :</div><br class="m_-5030093235766988749Apple-interchange-newline"><div><div style="word-wrap:break-word;line-break:after-white-space"><div><blockquote type="cite"><div><div><font color="#00afcd"><br></font>So I wonder if any of you have had any thoughts about what Swift's parentheses-related&nbsp;future (or evolutionary baggage) will be?<br><font color="#00afcd"><br></font></div></div></blockquote><br></div><div>I really wish swift used the concept of tuples **exclusively** for all purposes that involve parentheses, as well as dividing tuples into two categories:</div><div>- Bare tuples, which do not have labels.</div><div>- Rich tuples, which do.</div><div>As a consequence, here's a list of statements that would become true:</div><div>- All functions take exactly one parameter, which is a tuple.</div><div>- All closures (a.k.a. function pointers) take exactly one parameter, which is a bare tuple.</div><div>- All functions return exactly one parameter, which is a tuple.</div><div>- Pattern matching is done on a single bare tuple using a single bare tuple pattern.</div><div><br></div><div><div>The currently ongoing proposal to make a single-element tuple auto-flatten would work extremely well with this idea, by making all these changes completely backward-compatible.</div></div></div></div></blockquote><br></div><div>If I have well understood, Swift has evolved away from this.</div><div><br></div><div>If what you describe were true, added to the fact that there is no such thing as a one-element tuple in the language, then (A,B) -&gt; C and ((A, B)) -&gt; C could not be distinguished, for the simple reason that ((A, B)) -&gt; C could not be defined.</div><div><br></div><div>For&nbsp;((A, B)) -&gt; C&nbsp;to be defined, we'd need a function that takes exactly one parameter, which is a tuple (your idea), whose single element is a tuple (oops, there is no single-valued tuples).</div><div><br></div><div>No opinion here, just they way I have understood recent Swift history.</div><div>Gwendal</div><br></div></div></blockquote></div><br></div></div></div></div></blockquote></div><br></div>
</div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>