<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 Jul 1, 2016, at 1:30 AM, Taras Zakharko via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Jordan, Thanks for the very insightful explanation! It all makes a lot of sense in perspective.&nbsp;</div><div class=""><br class=""></div><div class="">Apparently I was thinking about this issue a bit while I was sleeping, and now it seems to me that part of the problem is because one strives for the function signature to be linguistically meaningful (as in natural language meaningful). It was mentioned that argument labels often don’t make much sense when detached from the function name, and that some function seem to have semantically compatible signatures and some don’t, e.g. the example of &nbsp;drawLineTo(x: Float, y: Float) and drawLineWith(angle: Float, distance: Float)</div><div class=""><br class=""></div><div class="">So this is actually a linguistic problem. More precisely, its a problem of predicate frames/argument semantics. Consider verbs like ‚hit' and ‚kill'. In term of precise semantics, we can model them as something like</div><div class=""><br class=""></div><div class="">kill(killer:victim:)</div><div class="">hit(hitter:victim:)</div><div class=""><br class=""></div><div class="">However, the actual status of the arguments here is compatible. Both verbs describe asymmetric actions, with one argument playing an active role in (negatively) changing the state of the other , passive one. So both are compatible with a broad metatype (what we often call predicate type in linguistics)</div><div class=""><br class=""></div><div class="">P(agent:undergoer:)</div><div class=""><br class=""></div><div class="">However, there are plenty of verbs that are quite different. Like go(person:to). Also two arguments, but the semantic status of them is very different.&nbsp;</div><div class=""><br class=""></div><div class="">If that is really the case, then there is indeed no general solution which keeps the argument labels semantically meaningful. But there is still a potential conflict with the tuple/function signature labels. &nbsp;</div><div class="">The only reasonable choice that comes to my mind is to completely drop argument labels in closure variables and just look at the argument type. Basically, by assigning function variables, we drop any semantics and just look at the overall structure (cardinality/argument types)</div><div class=""><br class=""></div><div class="">&nbsp;In more detail:</div><div class=""><br class=""></div><div class="">1. Maintain that argument labels are not part of the type, but merely hints for the function dispatch/programmer convenience</div></div></div></blockquote><div><br class=""></div><div>They are not merely hints, they are part of the full name of the function. Functions with different names are different functions, even if they share the same base name. That is, they are syntactically meaningful.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">2. <b class="">Disallow</b> argument labels in closure variables. &nbsp;I.e.:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; var fun = drawLineTo(x:y:)&nbsp;</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;has type (Float, Float) -&gt; (), which makes the variable explicitly compatible with any &nbsp;function of cardinality 2 that takes Float arguments. At the sae time, any declaration like&nbsp;</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp; var fun : (x: Float, y: Float) -&gt; ()&nbsp;</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;should be illegal. This further makes clear that tuples and functions are not the same thing.&nbsp;</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">3. In the long term, maybe consider <b class="">removing</b> <b class="">labels from tuples</b>. At the same time, there should be a new mechanism in place that allows one to elevate tuples to structs, with properties taking the role of the current tuple labels (like Python’s namedtuple)</div><div class=""><br class=""></div><div class="">An alternative, in order to keep the cake and eat it too, would be something along the lines of making predicate types explicit. E.g. creating some sort of function ‚semantic metatype‘ and declaring function conformance to this metatype. But I can’t imagine that it is a good idea. Natural languages are really not a good source of inspiration in this regard.&nbsp;</div><div class=""><br class=""></div><div class="">Best,&nbsp;</div><div class=""><br class=""></div><div class="">&nbsp;Taras</div><div class=""><br class=""></div><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 01 Jul 2016, at 05:33, Jordan Rose &lt;<a href="mailto:jordan_rose@apple.com" class="">jordan_rose@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On Jun 30, 2016, at 13:36, Taras Zakharko via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 30 Jun 2016, at 22:11, Austin Zheng &lt;<a href="mailto:austinzheng@gmail.com" class="">austinzheng@gmail.com</a>&gt; wrote:</div><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">As for the label semantics, Swift's current behavior is actively misleading, please see the example in the prior email. There are no meaningful semantics in the label, because implicit conversion between differently-labeled function types means that there is no way to usefully enforce these invariants to begin with.</div></div></div></blockquote><div class=""><br class=""></div><div class="">That is a good point. I admit to not knowing this (I strongly expected that labels would be semantically meaningful). But what exactly is the status of the argument labels than in Swift? Just a documentation device &nbsp;for the programmer and a &nbsp;hint for the compiler to do function dispatch? But if the compiler indeed does dispatch on argument labels, then they are not completely void of semantics, are they? &nbsp;As I mentioned before, I think the problem here is much deeper.&nbsp;</div><div class=""><br class=""></div><div class="">The state of affairs I would prefer is something along these lines:</div><div class=""><br class=""></div><div class="">1. Labels are semantically meaningful</div><div class="">2. There is an explicit casting system for function signatures</div><div class="">3. This casting system should be in close correspondence to tuples. The "function argument lists look sort of like tuples“ is a very compelling reason actually, because of the principle of the least surprise. If I have two things in the language that look very similar, then its very confusing if they &nbsp;exhibit very different behaviour. Again, I am not proposing that one goes back to model functions in terms of tuples. But as long as there is a surface resemblance (and an obvious morphisms between the two), at least some aspects of their design should be kept in sync.&nbsp;</div><div class=""><br class=""></div><div class="">But again, this touches on some deep design decisions for the language, so I — as an amateur — don’t feel in my plate discussing this here. I believe that there currently might be some inconsistencies in the language design that should be sealed with (but maybe they are no inconsistencies at all and I simply have false expectations).&nbsp;</div></div></div></div></blockquote><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Language history, a.k.a. story time!</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">We started out with the “perfect” model of a function type being a map from a tuple to a tuple. Different argument labels were just overloads. It really was quite a simple model, other than not having 1-tuples. Well, and variadics and default values and trailing closures didn’t make sense anywhere but in functions, but still. Very simple.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">(And inout. And autoclosure. And maybe a few more.)</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Then we hit a snag: naming guidelines. We wanted argument labels to be something people felt comfortable using, something that would be encouraged over a sea of unlabeled arguments. But even before the Swift 3 naming conventions were hammered out, the natural names for argument labels didn’t seem to match the names you’d want to use in the function. So we split the names of parameters off from the names of tuple elements.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">(This was precipitated by wanting to import Objective-C methods, but I think it would have come up regardless.)</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">As seen earlier in the thread, argument labels don’t make for good tuple element labels. Especially with the Swift 3 guidelines, argument labels usually don’t make sense without the context provided by the base name, and two methods that happen to share argument labels might not actually be very similar, while two methods that are duals of each other might have different argument labels due to, well, English (e.g. 'add(to:)' vs. 'remove(from:)’).</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">The real blow, however, came with that very first idea: that we could treat methods with different argument labels as simple overloads in type. This led to poor diagnostics where the compiler couldn’t decide whether to believe the types or the argument labels, and might tell you you have the wrong argument labels rather than a type mismatch. For pretty much every Apple API, this was the wrong decision. On top of all that, it was really hard to refer to a method when you<span class="Apple-converted-space">&nbsp;</span><i class="">didn’t</i>&nbsp;want to call it. (Most methods with the same base name still have unique labels, so you don’t need the types to disambiguate.)</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">So we introduced the notion of “full names”, which are the things you see written as ‘move(from:to:)` (and which are represented by DeclName in the compiler). Almost immediately diagnostics got better, testing optional protocol requirements got shorter, and a lot of compiler implementation got simpler.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">And then we kind of got stuck here. We have full names used throughout the compiler, but tuple labels still appear in types. They’re still used in mangling. We got rid of the “tuple splat” feature, but still model out-of-order arguments as “tuple shuffles”. And we allow a number of conversions that<span class="Apple-converted-space">&nbsp;</span><i class="">look</i>&nbsp;like they should be invalid, but aren’t.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">(And it’s important that we continue allowing them, or at least some of them, because we want to be able to pass existing functions to things like map and reduce without worrying about conflicting labels.)</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">So we’ve given up the perfect ideal of tuple-to-tuple. But we did it because we value other things more than that ideal: variadics, default values, trailing closures, inout, autoclosure, distinct argument labels and parameter names, referencing a function by full name, and diagnostics that better match the user’s likely intent (particularly given the naming guidelines and existing libraries). I think that’s a worthwhile trade.</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Jordan</div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">P.S. Anyone is allowed to think this is<span class="Apple-converted-space">&nbsp;</span><i class="">not</i>&nbsp;a worthwhile trade! But part of the purpose of this story is to show that we’re already 90% of the way towards making tuples and function arguments completely separate, even if they have similar syntax. This proposal gets us to maybe 95%.</div></div></blockquote></div><br class=""></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>