> On 30 Jun 2016, Chris Lattner wrote:
> 
> The review of "SE-0111: Remove type system significance of function argument 
> labels" begins now and runs through July 4. The proposal is available here:
> 
>       
> https://github.com/apple/swift-evolution/blob/master/proposals/0111-remove-arg-label-type-significance.md
>  
> <https://github.com/apple/swift-evolution/blob/master/proposals/0111-remove-arg-label-type-significance.md>
> What is your evaluation of the proposal?

+1. With the way the community has settled using argument labels, it seems 
clear to me that argument labels are part of a function's name and should not 
affect its type.

What we currently have technically works because the compiler is quite lenient 
in type conversions between different argument labels. But since there are 
corner cases lurking where labels in the function type matter (as demonstrated 
in the proposal), it's best we get rid of them entirely for clarity. As it has 
been pointed out, the status quo also complicates the overload resolution 
process and causes confusing error messages when the compiler can't tell if 
your argument labels are wrong or argument types. We're better without that 
complexity.

Further, I think removing this oddity could make function application with 
tuples feasible again (a.k.a the simple form of "tuple splatting" with all 
arguments in the tuple) by requiring to fully name the function before passing 
the arguments tuple:

    func doSomething(x: Int, y: Int) -> Bool { return true }
    func doSomething(any: Any) -> Bool { return false } // This can't possibly 
be considered below.
    
    let args = (1, 2)
    let named = (x: 1, y: 2)
    let f = doSomething(x:y:)
    f(args)                 // Unambiguous call, if the syntax is made legal 
(again).
    doSomething(x:y:)(args) // So is this.
    doSomething(args)       // This would still be an error as per SE-0029 
<https://github.com/apple/swift-evolution/blob/master/proposals/0029-remove-implicit-tuple-splat.md>.
    let tuples = [(1, 2), (3, 4), (5, 6)]
    print(tuples.map(f)) // This would be allowed. (Confusingly it already 
works despite SE-0029!)

In particular, you couldn't apply a `func` function with a tuple (which was 
what SE-0029 removed) but you could apply a qualified function reference 
(SE-0021 
<https://github.com/apple/swift-evolution/blob/master/proposals/0021-generalized-naming.md>)
 as well as a function value (i.e. a named closure) with a tuple, because both 
of them have set in stone their argument list length before the tuple 
application and thus suffer from none of the disadvantages listed in the 
motivation for SE-0029 
<https://github.com/apple/swift-evolution/blob/master/proposals/0029-remove-implicit-tuple-splat.md#motivation>.
 That would of course need a separate proposal and can be delayed until Swift 3 
has been released.

> Is the problem being addressed significant enough to warrant a change to 
> Swift?

Yes.

> Does this proposal fit well with the feel and direction of Swift?

I think so.

> If you have used other languages or libraries with a similar feature, how do 
> you feel that this proposal compares to those?

Well, we've had argument labels in Objective-C but since it's not a strongly 
typed language I don't think it applies for comparison. However, I naturally 
feel argument labels in Objective-C as well are part of the function's name 
rather than its type.

> How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study?

More than a quick reading. I've suggested a similar idea before but didn't 
motivate it well enough to gain interest back then. Big thanks to Austin for 
driving it forward this time!

— Pyry

PS. Can anybody explain why the last example in my code above turned out to be 
allowed even though SE-0029 seems to prohibit it? Here's a more comprehensive 
test which made me positively surprised that it still worked after SE-0029:

    let f: (Int, Int) -> Int = (+)
    let x = (1, 2)
    let x, y = (3, 4)
    f(1, 2) //=> 3
    // f((1, 2))                          // Does not compile, as expected 
(SE-0029).
    // f(x)                               // Does not compile, as expected.
    [x, y].map(f) //=> [3, 7]             // Surprisingly compiles, but why?
    let g: ((Int, Int)) -> Int = f        // Huh? So `f` can coerce to a 
`(tuple) -> Int`?
    g(x) //=> 3                           // So this is what made `map` work 
above.
    (f as ((Int, Int)) -> Int)(x) //=> 3  // This works too, didn't expect it 
to.
    [x, y].map(+)  //=> [3, 7]            // Finally, why is this allowed 
despite SE-0029?

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

Reply via email to