Shorthand Argument Names in Swift

No day go by without me learning something new about Swift and that is probably one of the aspects I enjoy most about the language. Like most developers, I like exploring new technologies.

One of the reasons Swift is loved by many developers is its optimization for conciseness and elegance without compromising readability. Shorthand argument names are a fine example of this feature.

What Are Shorthand Argument Names

You probably know that you can refer to the arguments of an inline closure using shorthand argument names. Take a look at the following examples to understand how shorthand argument names are used.

// Without Shorthand Argument Names
let groceries = ["milk", "eggs", "butter", "flowers"]

let uppercasedGroceries = groceries.map { (item) -> String in
    item.uppercased()
}
// With Shorthand Argument Names
let groceries = ["milk", "eggs", "butter", "flowers"]

let uppercasedGroceries = groceries.map {
    $0.uppercased()
}

The shorthand argument names are automatically provided by Swift. The first argument can be referenced by $0, the second argument can be referenced by $1, and so on.

This is very convenient if the body of the inline closure is short and easy to understand without explicit argument names. The syntax becomes especially convenient for short inline closures like we discussed last week.

let filteredNumbers = numbers.filter { ($0 % 2) == 0 }

We can omit the argument names as well as the return type, which is inferred by the compiler. This also means we can omit the in keyword, which separates the arguments and the return type from closure's body.

Closures Arguments

A few weeks ago, I came across an interesting article of Natasha Murashev, also known as Natasha The Robot, in which she discusses an interesting technique to initialize constants using closures. Natasha's example looked something like this (updated for Swift 3).

let purpleView: UIView = {
    let view = UIView()
    view.backgroundColor = .purple
    return view
}()

This looks fine, but more interesting is the implementation that makes use of shorthand argument names. I have to admit that I didn't know this was possible in Swift.

let purpleView: UIView = {
    $0.backgroundColor = .purple
    return $0
}(UIView())

But how is it possible that this works? It may look odd at first glance. But if you deconstruct the example, it makes perfect sense.

We are using an inline closure to create and configure the view, which we assign to the purpleView constant. Like a function, we invoke the closure by appending a pair of parentheses to the closure. This technique is also used to lazily initialize properties.

In the above example, we pass an argument to the closure just like we pass arguments to a function. The UIView instance we create and pass to the closure becomes available in the closure. And, as a result, we can refer to the argument using its shorthand argument name, $0.

Once you understand how it works, you realize it isn't difficult to understand and certainly not magical. This is why I love working with Swift.