Lambdas

function types

Swift support function types. Values of that types can be anonymous functions, lambdas or reference to the class method. Each function belongs to corresponding function type.

To declare function type you list types of parameters in parentheses and after arrow specify return type like (A, B) -> C.

The parameter types list may be empty: () -> A.

Use Void type when no return value: (A, B) -> Void.

func addTwoInts(_ a: Int, _ b: Int) -> Int {
    return a + b
}
func multiplyTwoInts(_ a: Int, _ b: Int) -> Int {
    return a * b
}
// both functions are (Int, Int) -> Int

var mathFunction: (Int, Int) -> Int = addTwoInts

lambda expression

In Swift, a lambda is called a closure.

// { (parameters) -> return type in
//    statements
//}

reversedNames = names.sorted(by: { (s1: String, s2: String) -> Bool in
    return s1 > s2
}) // with full syntax

You can skip type names for parameters and return value when them are known. For example lambda is used as parameter of function.

reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )

Single-expression lambda can omit the return keyword.

reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )

Swift can generate default names for the lambda parameters: $0, $1, $2 and etc.

reversedNames = names.sorted(by: { $0 > $1 } )

Operators can be used to replace common closures.

reversedNames = names.sorted(by: > )

higher-order function

A higher-order function is a function that takes functions as parameters, or returns a function.

func someFunctionThatTakesAClosure(closure: () -> Void) {
    // function body goes here
}

// Here's how you call this function without using a trailing closure:
someFunctionThatTakesAClosure(closure: {
    // closure's body goes here
})

Last lambda argument can be placed outside the parentheses. Such syntax is also known as trailing lambda.

// with a trailing
someFunctionThatTakesAClosure() {
    // trailing closure's body goes here
}

If the lambda is the only argument to that call, the parentheses can be omitted entirely.

someFunctionThatTakesAClosure {
    // trailing closure's body goes here
}

closure

A lambda expression / local function can capture constants and variables from the surrounding context in which it’s defined. Constants and variables will be accessible even if the original scope that defined them no longer exists. (Read more about closure.)

func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    
    func incrementer() -> Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementer
}