SWIFT NOTES - CLOSURE

Thanks to the host of technologies provided by the Swift compiler, the closure comes with a bunch of syntactic sugars that could sweet you to diabetes.

The full syntax of a closure:

{
  (parameters) -> retrunType in
  ... statements ...
}

Here is an example that uses the array’s method sorted to sort an array of word.

var words = [ "Dolor", "eum", "id", "suscipit", "necessitatibus", "quod", "hic", "dignissimos" ]

let sortedWords = words.sorted({
  (lhs: String, rhs: String) -> Bool in
  return lhs < rhs
})

As the sugars introduced in one by one, we will cut the lines above into an incredibly one-liner.

Sugar #0 – trailing closure

Often, closure parameter is placed last in parameter list. Swift thus provides trailing closure, which means your can write the inline closure just outside the parameter list, following the closing ).

Furthermore, if the closure is the only parameter, then the parenthesis can be omitted.

// trailing closure
let sortedWords = words.sorted/*()*/ {
  (lhs: String, rhs: String) -> Bool in
  return lhs < rhs
}

Sugar #1 – return type inference

return type can be inferred by swift compiler.

// omit return type
let sortedWords = words.sorted {
  (lhs: String, rhs: String) /*-> Bool*/ in
  return lhs < rhs
}

Sugar #2 – parameter type inference

parameter types can be inferred by swift compiler as well.

// omit parameter types
let sortedWords = words.sorted {
  (lhs/*: String*/, rhs/*: String*/) /*-> Bool*/ in
  return lhs < rhs
}

Sugar #3 – parenthesis-less

Since no type annotation is needed, the parenthesis can be omitted.

// omit parenthesis
let sortedWords = words.sorted {
  /*(*/lhs/*: String*/, rhs/*: String)*/ /*-> Bool*/ in
  return lhs < rhs
}

Sugar #4 – auto return for single expression closure

If the closure has one statement, then the return statement can also be inferred.

// omit 'return'
let sortedWords = words.sorted {
  /*(*/lhs/*: String*/, rhs/*: String)*/ /*-> Bool*/ in
  /*return*/ lhs < rhs
}

//then we got:
let sortedWords = words.sorted { lhs, rhs in lhs < rhs }

Sugar #5 – shorthand parameter name

Swift provides shorthand parameter names: $0 for the 1st parameter, $1 for the 2nd parameter, and so on. And as an side effect, the whole (parameters) -> returType in statement can be completely omitted

// use shorthand parameters, omit the whole 'in' statement
let sortedWords = words.sorted {
  /*(lhs: String, rhs: String) -> Bool in*/
  /*return*/ $0 < $1
}

// then we got:
let sortedWords = words.sorted { $0 < $1 }

Sugar #6 – operator as a closure

In swift, operator is a function, which in turn is a special closure, so…

// comes operator!
let sortedWords = words.sorted(<)