> 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
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution