Why Apple's closure declarations missing argument labels


As I read through UIKit, most of the time I see closures (as a function parameter) with missing argument labels like this: func fooClosure(fooClosure: (Bool) -> Swift.Void)

In some cases I can guess what it stands for, in others I don 't.


Take a look at one of UIActivityViewController's closure (as a type alias):

public typealias UIActivityViewControllerCompletionWithItemsHandler = (UIActivityType?, Bool, [Any]?, Error?) -> Swift.Void

What does 3rd type stand for? I have to look at the Objective-C version of the code to know these are returnedItems.

Why it is not implemented that way: (note the activityItems label)

public typealias UIActivityViewControllerCompletionWithItemsHandler = (UIActivityType?, Bool, _ activityItems: [Any]?, Error?) -> Swift.Void

Edit: - Is this just a temporary state (since swift is not fully integrated in these frameworks)? Code is less readable without argument labels.

Show source
| swift   | ios   | swift3   | closures   2017-01-06 21:01 3 Answers

Answers ( 3 )

  1. 2017-01-06 22:01

    As of Swift 3, keywords are no longer a part of a closure's type, thus they don't (and can't) appear anywhere a type is expected, such as in type alias and func declarations.

    See the answer in this post for more information.

  2. 2017-01-06 22:01

    Closures are designed to be versatile. You don't have parameter names because the function you create to pass in could be wildly different from the function someone else rights.

    Remember, the parameter names belong to the function.

    To illustrate, when I create a function, I would do it like this:

    func getUser(for name: String) -> User {
        // Stuff here...

    I add the label so myself and others know how to properly use the function.

    A closure parameter is not a function, you pass in a function. The function one person writes could create a cheese burger, while another person could write one that rotates a view 180ยบ and segue to a new view controller.

    With an example from Apples Documentation on UIView, there is an ending closure called completion. As this name suggests, this function is fired when the animation completes. Now the docs do explain that the Bool value tells you whether the animation is complete or not, something that is not obvious from the function itself.

    If your not sure what the parameter is used for (example being above), look at the docs.

    Hope this answers your question.

  3. 2017-01-07 03:01

    The problem is that this is a function signature typealias generated by machine, and the machine isn't doing what you would like it to do. Consider the following Objective-C declaration:

    typedef void (^MyCoolType)(NSString* __nullable name);

    The Swift generated interface for that is:

    public typealias MyCoolType = (String?) -> Swift.Void

    As you can see, name got stripped out; it is nowhere to be seen.

    Nothing stops you from defining a function signature typealias with internal labels, in Swift. This is legal:

    public typealias MyCoolType = (_ name:String?) -> Void

    But that does not happen to be how the generated interface is generated from Objective-C.

◀ Go back