<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jun 9, 2017, at 4:34 PM, Jens Persson <<a href="mailto:jens@bitcycle.com" class="">jens@bitcycle.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="">The analogy of the special first parameter label was relevant (for me) in that it was a special rule that was invented to resolve a problem/situation with no clear best solution. Probably most people agree now that the current simpler and more uniform rule set for parameter labels are obviously better. It was possible to escape the ugly special case of the first parameter, after all.</div><div class=""><br class=""></div><div class="">Similarly, I wonder if the parentheses-related mess actually can be simpler and more uniform, after all. I remember a lot of discussions in which people argued that Swift couldn't and/or shouldn't get rid of the special first parameter label rules.</div><div class=""><br class=""></div>I'm not a compiler hacker and I have no idea exactly what aspects of the language is easy/hard/impossible to change once Swift is binary stable.<div class=""><br class=""><div class="">My concrete concerns are that the messy parentheses-related parts of the language will continue to be messy for ever.</div><div class="">I have no idea if there is any actual reason to worry about that, but ABI stability was originally intended for Swift 3, and then it was postponed because some stuff needed to be done before ABI stability. Now I'm just worried that solving the parentheses situation is something that needs to be done before ABI stability. Please correct/enlighten me!</div></div><div class=""><br class=""></div></div></div></blockquote><div><br class=""></div><div>Ah, rest assured that ABI stability (likely*) has little to do with your concerns. In theory, some post-ABI-stability Swift version could rename every single keyword and replace curly braces with “begin/end” and parens with emoji without affecting the ABI. Similarly, syntactic sugar and destructuring tuples shouldn’t affect ABI*. Source stability is what you’re likely confusing this with, which can be a little nebulous.</div><div><br class=""></div><div><br class=""></div><div>* Unless you’re proposing a change to the semantics of the language that could affect e.g. name mangling or the type metadata hierarchy, then that would be ABI-affecting. For example, proposing that all functions must only take a single tuple rather than multiple arguments could affect the runtime representation of function types. But even then, there are approaches to mitigate this, so such a proposal would likely present an ABI migration strategy.</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="">/Jens</div><div class=""><br class=""></div><div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Sat, Jun 10, 2017 at 12:50 AM, Michael Ilseman <span dir="ltr" class=""><<a href="mailto:milseman@apple.com" target="_blank" class="">milseman@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto" class=""><div class=""><div class="h5"><div class=""><br class=""></div><div class=""><br class="">On Jun 9, 2017, at 2:10 PM, Jens Persson via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class="">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 class="">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 class=""><div class=""><br class=""></div><div class=""><div class="">The following program demonstrates how it can be done in Swift 3.1 and 3.2:</div><div class=""><br class=""></div><div class="">func compose<T, U, V>(_ g: @escaping (U) -> V, _ f: @escaping (T) -> U) -> (T) -> V {</div><div class=""> return { x in g(f(x)) }<br class=""></div><div class="">}</div><div class="">func sum(_ a: Int, _ b: Int) -> Int { return a + b }</div><div class="">func square(_ a: Int) -> Int { return a * a }</div><div class="">let squaredSum = compose(square, sum)</div><div class="">let result = squaredSum((3, 4)) // A bit unexepected with a tuple here but ok ...</div><div class="">print(result) // 49</div><div class="">// Well, it worked, not flawlessly but we did manage to write</div><div class="">// a function composition function and we composed sum</div><div class="">// and square, and we could call it and get a correct result.</div><div class=""><br class=""></div><div class=""> </div><div class="">And this program demonstrates what happens if you try it in Swift 4:</div><div class=""><br class=""></div><div class="">func compose<T, U, V>(_ g: @escaping (U) -> V, _ f: @escaping (T) -> U) -> (T) -> V {</div><div class=""> return { x in g(f(x)) }</div><div class="">}</div><div class="">func sum(_ a: Int, _ b: Int) -> Int { return a + b }</div><div class="">func square(_ a: Int) -> Int { return a * a }</div><div class="">// let squaredSum = compose(square, sum) // Error! (without the compose-variant below)</div><div class=""><br class=""></div><div class="">// The error message is:</div><div class="">// Cannot convert value of type `(Int, Int) -> Int` to</div><div class="">// expected argument type `(_) -> _`</div><div class=""><br class=""></div><div class="">// That's it, it is simply not possible!</div><div class=""><br class=""></div><div class="">// You'd have to write special variants of the compose func for every combination</div><div class="">// of parameter counts! For example, in order to get this sum and square</div><div class="">// example working, this specific variant must be written:</div><div class="">func compose<T, U, V, W>(_ g: @escaping (V) -> W, _ f: @escaping (T, U) -> V) -> (T, U) -> W {</div><div class=""> return { (x, y) in g(f(x, y)) }</div><div class="">}</div><div class="">// Now it will work:</div><div class="">let squaredSum = compose(square, sum)</div><div class="">// But only thanks to that awfully specific compose func variant ...</div></div><div class="">// We would have to write a lot more variants for it to be practically usable on pretty much any common function.</div><div class=""><br class=""></div><div class="">I'm sure some will say:</div><div class="">"no regular developers use function composition anyway so why ..."</div><div class="">or</div><div class="">"It's not very swifty to use free functions and higher order functions like that."</div><div class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">I'm a regular programmer and I like to be able to write basic, useful abstractions.</div><div class="">It's no fun when the language forces you to write lots of specific variants of your generic code.</div><div class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">Can Swift's parentheses-situation be sorted out before ABI stability?</div><div class="">Otherwise it would be a bit like if Swift had kept the special rule for the first parameter, only much worse.</div><div class=""><br class=""></div></div></div></div></blockquote><div class=""><br class=""></div></div></div><div class="">Out of curiosity, how do you think this would impact ABI? What are your concrete concerns here?</div><div class=""><br class=""></div><div class="">I don't think the analogy of first parameter label is relevant, as that needn't be ABI. </div><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class="">/Jens</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Fri, Jun 9, 2017 at 7:17 PM, Gor Gyolchanyan <span dir="ltr" class=""><<a href="mailto:gor@gyolchanyan.com" target="_blank" class="">gor@gyolchanyan.com</a>></span> wrote:<br class=""><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" class="">Yes, except why would you need to define `((A, B)) -> 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 *looks* like it takes a single 2-element tuple - you can! Seems to me that the difference between `((A, B)) -> C` and `(A, B) -> 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 class=""><div class="m_-5451479047364055047h5"><div class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Jun 9, 2017, at 6:18 PM, Gwendal Roué <<a href="mailto:gwendal.roue@gmail.com" target="_blank" class="">gwendal.roue@gmail.com</a>> wrote:</div><br class="m_-5451479047364055047m_-5030093235766988749Apple-interchange-newline"><div class=""><div style="word-wrap:break-word" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">Le 9 juin 2017 à 17:12, Gor Gyolchanyan via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> a écrit :</div><br class="m_-5451479047364055047m_-5030093235766988749Apple-interchange-newline"><div class=""><div style="word-wrap:break-word;line-break:after-white-space" class=""><div class=""><blockquote type="cite" class=""><div class=""><div class=""><font color="#00afcd" class=""><br class=""></font>So I wonder if any of you have had any thoughts about what Swift's parentheses-related future (or evolutionary baggage) will be?<br class=""><font color="#00afcd" class=""><br class=""></font></div></div></blockquote><br class=""></div><div class="">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 class="">- Bare tuples, which do not have labels.</div><div class="">- Rich tuples, which do.</div><div class="">As a consequence, here's a list of statements that would become true:</div><div class="">- All functions take exactly one parameter, which is a tuple.</div><div class="">- All closures (a.k.a. function pointers) take exactly one parameter, which is a bare tuple.</div><div class="">- All functions return exactly one parameter, which is a tuple.</div><div class="">- Pattern matching is done on a single bare tuple using a single bare tuple pattern.</div><div class=""><br class=""></div><div class=""><div class="">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 class=""></div><div class="">If I have well understood, Swift has evolved away from this.</div><div class=""><br class=""></div><div class="">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) -> C and ((A, B)) -> C could not be distinguished, for the simple reason that ((A, B)) -> C could not be defined.</div><div class=""><br class=""></div><div class="">For ((A, B)) -> C 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 class=""><br class=""></div><div class="">No opinion here, just they way I have understood recent Swift history.</div><div class="">Gwendal</div><br class=""></div></div></blockquote></div><br class=""></div></div></div></div></blockquote></div><br class=""></div>
</div></blockquote></span><span class=""><blockquote type="cite" class=""><div class=""><span class="">______________________________<wbr class="">_________________</span><br class=""><span class="">swift-evolution mailing list</span><br class=""><span class=""><a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a></span><br class=""><span class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank" class="">https://lists.swift.org/<wbr class="">mailman/listinfo/swift-<wbr class="">evolution</a></span><br class=""></div></blockquote></span></div></blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></body></html>