[swift-evolution] [Accepted] SE-0111: Remove type system significance of function argument labels

Pyry Jahkola pyry.jahkola at iki.fi
Fri Jul 8 04:02:12 CDT 2016


> Charlie Monroe wrote:
> 
> This hasn't occurred to me until now, but this will also elminate the following (right?):
> 
> public typealias XUURLRequestModifier = (request: NSMutableURLRequest) -> Void
> 
> Which is really nice since when expanded by Xcode, this automatically offers you the "request" label for the variable so you don't have to name it.

As far as I understood, no it won't eliminate that use case, and quite the contrary this is exactly the cosmetic change to the original proposal that the core team wanted to add. So your code above will work, but with the change that a closure `modifier` of type `XUURLRequestModifier` is called like `modifier(req)` from now on and not `modifier(request: req)`.

I think it's often missed in this discussion that there are not one but *two* cases where argument labels (or the lack of them) matter in Swift, and both of cases also affect auto-completion:

1) The first case is when calling a closure (which most often was passed to the current function as an argument). What the accepted proposal SE-0111 did was remove argument labels from those calls in all circumstances:

    func modifyRequest(modifier: XUURLRequestModifier) {
      // This autocompletes without labels as something like:
      modifier(<#request#>)
      // I.e. the cosmetic labels still appear as placeholders, AFAICT.
    }

Most of the time, the code that calls a closure is written once and run multiple times with various blocks, so simple mistakes that argument types won't catch get easily catched in unit tests or when testing the application.

2) The second, and much more common case in application-level code IMO is when passing a closure argument to a library function:

    // This, I think, would autocomplete as:
    frob.modifyRequest { (request: NSMutableURLRequest) -> Void in
      // I.e. now the cosmetic label becomes the default argument name.
    }

So this is where cosmetic labels matter most and nothing changed in this regard in the outcome of SE-0111.

* * *

For people longing to pass labels when *calling* closures, I think you should consider proposing the extended naming syntax idea (or some variant) where an N-argument closure can alternatively be bound to a name with N labels (see https://github.com/apple/swift-evolution/blob/master/proposals/0021-generalized-naming.md):

    // This closure is named `modify(request:)`
    let modify(request:): XUURLModifierRequest = { request in
      ...
    }
    modify(request: req)

    // The argument with label `modifier` is *locally* named `mod(req:)`.
    func example(modifier mod(req:): XUURLModifierRequest) {
      mod(req: someRequest)
    }

    example { request in ... }
    example(modifier: modify(request:))

Note that the local name `req(mod:)` wouldn't need to match the call site (except in type), and they really shouldn't either.

— Pyry
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160708/341beed3/attachment.html>


More information about the swift-evolution mailing list