Mostly I was just hedging my bets, but the main one I can think of is that enum 
cases still use tuples, which means they don’t have distinct argument labels 
and preserve the labels in switches. There’s also a bunch of implementation 
improvements we can make (like fixing mangling and printing of function types), 
but that’s not something swift-evolution cares about so much.

There are also some related things about how function arguments work that are 
probably better done the further we get here:
- Forwarding variadic parameters
- Generalized argument forwarding? That works with inout?
- Variadic generics

Someday!
Jordan


> On Jun 30, 2016, at 23:18, David Hart <da...@hartbit.com> wrote:
> 
> Great story! What gets us from 95% to 100%? :)
> 
> On 1 Jul 2016, at 05:33, Jordan Rose via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
>> 
>>> On Jun 30, 2016, at 13:36, Taras Zakharko via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 
>>>> On 30 Jun 2016, at 22:11, Austin Zheng <austinzh...@gmail.com 
>>>> <mailto:austinzh...@gmail.com>> wrote:
>>>> 
>>>> 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.
>>> 
>>> 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  for the 
>>> programmer and a  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?  As I mentioned before, I think the 
>>> problem here is much deeper. 
>>> 
>>> The state of affairs I would prefer is something along these lines:
>>> 
>>> 1. Labels are semantically meaningful
>>> 2. There is an explicit casting system for function signatures
>>> 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  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. 
>>> 
>>> 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). 
>> 
>> Language history, a.k.a. story time!
>> 
>> 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.
>> 
>> (And inout. And autoclosure. And maybe a few more.)
>> 
>> 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.
>> 
>> (This was precipitated by wanting to import Objective-C methods, but I think 
>> it would have come up regardless.)
>> 
>> 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:)’).
>> 
>> 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 didn’t want to call it. (Most methods with the 
>> same base name still have unique labels, so you don’t need the types to 
>> disambiguate.)
>> 
>> 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.
>> 
>> 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 look like they should be invalid, but aren’t.
>> 
>> (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.)
>> 
>> 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.
>> 
>> Jordan
>> 
>> P.S. Anyone is allowed to think this is not 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%.
>> 
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to