iOS 8 Programming Fundamentals with Swift: Swift, Xcode, and Cocoa Basics (2015)

Part I. Language

Chapter 2. Functions

Nothing is so characteristic of Swift syntax as the way you declare and call functions. Probably nothing is so important, either! As I said in Chapter 1, all your code is going to be in functions; they are where the action is.

Function Parameters and Return Value

A function is like one of those pseudo-scientific machines for processing miscellaneous stuff that you probably drew in your math textbook in elementary school. You know the ones I mean: with a funnel-like “hopper” at the top, and then a bunch of gears and cranks, and then a tube at the bottom where something is produced. A function is a machine like that: you feed some stuff in, the stuff is processed in accordance with what this particular machine does, and something is produced.

The stuff that goes in is the input; what comes out is the output. More technically, a function that expects input has parameters; a function that produces output has a result. For example, here’s a very silly but perfectly valid function that expects two Int values, adds them together, and produces that sum:

func sum (x:Int, y:Int) -> Int {

    let result = x + y

    return result

}

The syntax here is very strict and well-defined, and you can’t use Swift unless you understand it perfectly. Let’s pause to appreciate it in full detail; I’ll break the first line into pieces so that I can call them out individually:

func sum 1

    (x:Int, y:Int) 2

    -> Int { 3

        let result = x + y 4

        return result 5

}

1

The declaration starts with the keyword func, followed by the name of this function; here, it’s sum. This is the name that must be used in order to call the function — that is, in order to run the code that the function contains.

2

The name of the function is followed by its parameter list. It consists, minimally, of parentheses. If this function takes parameters (input), they are listed inside the parentheses, separated by comma. Each parameter has a strict format: the name of the parameter, a colon, and the type of the parameter. Here, our sum function expects two parameters — an Int, to which it gives the name x, and another Int, to which it gives the name y.

Observe that these names, x and y, are arbitrary and purely local (internal) to this function. They are different from any other x and y that may be used in other functions or at a higher level of scope. These names are defined so that the parameter values will have names by which they can be referred to in the code within the function body. The parameter declaration is, indeed, a kind of variable declaration: we are declaring variables x and y for use inside this function.

3

After the parentheses is an arrow operator ->, followed by the type of value that this function will return. Then we have curly braces enclosing the body of the function — its actual code.

4

Within the curly braces, in the function body, the variables defined as the parameter names have sprung to life, with the types specified in the parameter list. We know that this code won’t run unless this function is called and is actually passed values in its parameters.

Here, the parameters are called x and y, so we can confidently use those values, referring to them by those names, secure in the knowledge that such values will exist and that they will be Int values, as specified by our parameter list. Not only the programmer, but also the compiler can be sure about this.

5

If the function is to return a value, it must do so with the keyword return followed by that value. And, not surprisingly, the type of that value must match the type declared earlier for the return value (after the arrow operator).

Here, I return a variable called result; it was created by adding two Int values together, so it is an Int, which is what this function is supposed to produce. If I tried to return a String (return "howdy"), or if I were to omit the return statement altogether, the compiler would stop me with an error.

Note that the keyword return actually does two things. It returns the accompanying value, and it also halts execution of the function. It is permitted for more lines of code to follow a return statement, but the compiler will warn if this means that those lines of code can never be executed.

The function declaration, then, before the curly braces, is a contract about what kinds of values will be used as input and about what kind of output will be produced. According to this contract, the function expects a certain number of parameters, each of a certain type, and yields a certain type of result. Everything must correspond to this contract. The function body, inside the curly braces, can use the parameters as local variables. The returned value must match the declared return type.

The same contract applies to code elsewhere that calls this function. Here’s some code that calls our sum function:

let z = sum(4,5)

Focus your attention on the right side of the equal sign — sum(4,5). That’s the function call. It uses the name of the function; it has parentheses; and inside those parentheses, separated by comma, are the values to be passed to each of the function’s parameters. Technically, these values are called arguments. Here, I’m using literal Int values, but I’m perfectly free to use Int variables instead; the only requirement is that I use things that have the correct type:

let x = 4

let y = 5

let z = sum(y,x)

In that code, I purposely used the names x and y for the variables whose values are passed as arguments, and I purposely reversed them in the call, to emphasize that these names have nothing to do with the names x and y inside the function parameter list and the function body. These names do not magically make their way to the function. Their values are all that matter; their values are the arguments.

What about the value returned by the function? That value is magically substituted for the function call, at the point where the function call is made. It happens that in the preceding code, the result is 9. So the last line is exactly as if I had said:

let z = 9

The programmer and the compiler both know exactly what type of thing this function returns, so they also know where it is and isn’t legal to call this function. It’s fine to call this function as the initialization part of the declaration of the variable z, just as it would be to use 9 as the initialization part of that declaration: in both cases, we have an Int, and so z ends up being declared as an Int. But it would not be legal to write this:

let z = sum(4,5) + "howdy" // compile error

Because sum returns an Int, that’s the same as trying to add an Int to a String — and by default, you can’t do that in Swift.

Observe that it is legal to ignore the value returned from a function call:

sum(4,5)

That code is legal; it causes neither a compile error nor a runtime error. It is also sort of silly in this particular situation, because we have made our sum function go to all the trouble of adding 4 and 5 for us and we have then thrown away the answer without capturing or using it. However, there are lots of situations where it is perfectly reasonable to ignore the value returned from a function call; in particular, the function may do other things in addition to returning a value, and the purpose of your call to that function may be those other things.

If you can call sum wherever you can use an Int, and if the parameters of sum have to be Int values, doesn’t that mean you can call sum inside a call to sum? Of course it does! This is perfectly legal (and reasonable):

let z = sum(4,sum(5,6))

The only argument against writing code like that is that you might confuse yourself and that it might make things harder to debug later. But, technically, it’s quite normal.

Void Return Type and Parameters

Let’s return to our function declaration. With regard to a function’s parameters and return type, there are two degenerate cases that allow us to express a function declaration more briefly:

A function without a return type

No law says that a function must return a value. A function may be declared to return no value. In that case, there are three ways to write the declaration: you can write it as returning Void; you can write it as returning (), an empty pair of parentheses; or you can omit the arrow operator and the return type entirely. These are all legal:

func say1(s:String) -> Void { println(s) }

func say2(s:String) -> () { println(s) }

func say3(s:String) { println(s) }

If a function returns no value, then its body need not contain a return statement. If it does contain a return statement, its purpose will be purely to end execution of the function at that point.

This return statement will usually consist of return and nothing else. However, Void (the type returned by a function that returns no value) is an actual type in Swift, and a function that returns no value technically does in fact return a value of this type, which may be expressed as the literal (). (I’ll explain in Chapter 3 what the literal () really represents.) Thus, it is legal for such a function to say return (); whether it says that or not, () is what it returns. Writing return () — or return;, with a semicolon — can be useful to disambiguate in case Swift thinks I’m trying to return whatever is on the next line.

The call to a function that returns no value will usually be the only thing in its line of code, because no value is being returned that could be used by anything else in the line. Still, it is legal (though unlikely) to capture the returned () value in a variable typed as Void; for example:

let pointless : Void = say1("howdy")

A function without any parameters

No law says that a function must take any parameters. If it doesn’t, the parameter list in the function declaration can contain Void or can be completely empty. But you can’t omit the parameter list parentheses themselves! They will be present in the function declaration, after the function’s name. So, these are both legal:

func greet1(Void) -> String { return "howdy" }

func greet2() -> String { return "howdy" }

Obviously a function can lack both a return value and parameters; these are all ways of expressing the same thing:

func greet1(Void) -> Void { println("howdy") }

func greet2() -> () { println("howdy") }

func greet3() { println("howdy") }

I can’t emphasize too strongly that every function call must be accompanied by parentheses. Those parentheses will be empty if the function takes no parameters, but they must be present. For example:

greet1()

Notice the parentheses!

Function Signature

If we ignore for a moment the parameter names in the function declaration, we can completely characterize a function by the types of its inputs and its output, using an expression like this:

(Int, Int) -> Int

That in fact is a legal expression in Swift. It is the signature of a function. In this case, it’s the signature of our sum function. Of course, there can be other functions that take two Int parameters and return an Int — and that’s just the point. This signature characterizes all functions that have this number of parameters, of these types, and that return a result of this type. A function’s signature is, in effect, its type — the type of the function. The fact that functions have types will be of great importance later on.

The signature of a function must include both the parameter list (without parameter names) and the return type, even if one or both of those is empty; so, the signature of a function that takes no parameters and returns no value may be written Void -> Void, or () -> ().

External Parameter Names

A function can externalize the names of its parameters. This means that the names have to appear in a call to the function, labeling each parameter that has an external name. There are several reasons why this is a good thing:

§  It clarifies the purpose of each parameter; each parameter name can give a clue as to how that parameter contributes to the behavior of the function.

§  It distinguishes one function from another; two functions can have the same name and signature but different external parameter names.

§  It helps Swift to interface with Objective-C and Cocoa, where method parameters have externalized names.

To externalize a parameter name, put the external name before the internal parameter name, separated by a space, in the function declaration. The external name can be the same as the internal name, or different; if it is to be the same, a shorthand is provided: put a # before the internal name (and the space is then optional).

Here’s the declaration for a function that concatenates a string with itself a given number of times:

func repeatString(s:String, #times:Int) -> String {

    var result = ""

    for _ in 1...times { result += s }

    return result

}

That function’s first parameter has an internal name only, but its second parameter has an external name, which is to be the same as its internal name, namely times. And here’s how to call it:

let s = repeatString("hi", times:3)

In the call, as you can see, the external name precedes the argument, separated by a colon.

As I’ve already said, a parameter’s external name can be different from its internal name. Let’s say that in our repeatString function we prefer to use times purely as an external name, with a different name — say, n — as the internal name. Then the declaration would look like this:

func repeatString(s:String, times n:Int) -> String {

    var result = ""

    for _ in 1...n { result += s}

    return result

}

In the body of that function, there is now no times variable available; times is purely an external name, for use in the call. The internal name is n, and that’s the name the code refers to.

TIP

The existence of external names doesn’t mean that the call can use a different parameter order from the declaration. For example, our repeatString expects a String parameter and an Int parameter, in that order. The order can’t be different in the call, even though the label might appear to disambiguate which argument goes with which parameter. (In a moment, though, I’ll give an apparent exception to this rule.)

Our repeatString function follows a common convention that the first parameter has no external name, while the others do. One reason for this convention is that the first parameter often doesn’t need an external name, because the function name usually clarifies sufficiently what the first parameter is for — as it does in the case of repeatString (it repeats a string, which the first parameter should provide). Another reason — much more important in real life — is that this convention allows Swift functions to interface with Objective-C methods, which typically work this way.

For example, here’s the Objective-C declaration for a Cocoa NSString method:

- (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target

                                        withString:(NSString *)replacement

This method takes two NSString parameters and returns an NSString. The external name of the second parameter is obvious — it’s withString. But it’s a bit less obvious what the name of the first parameter is. On the one hand, you could argue that it’sstringByReplacingOccurrencesOfString. On the other hand, that’s not really the name of the parameter; it’s more the name of the method. Actually, the formal name of the method is the whole thing: stringByReplacingOccurrencesOfString:withString:. But Swift function call syntax has parentheses distinguishing the function name from the external parameter names. So when Swift wants to call this Objective-C method, the first thing-before-a-colon becomes the name of the function, before the parentheses, and the second thing-before-a-colon becomes the external name of the second parameter, inside the parentheses. A Swift String and a Cocoa NSString are automatically bridged to one another, so you can actually call this Cocoa method on a Swift String, like this:

let s = "hello"

let s2 = s.stringByReplacingOccurrencesOfString("ell", withString:"ipp")

// s2 is now "hippo"

The need for Swift to interface readily with Objective-C is so important, in fact, that Swift provides a special shorthand: if a function is a method (that is, if it is declared at the top level of the declaration of an enum, struct, or class), then this convention about which parameter names are externalized is followed automatically. You can declare separate external names for the parameters if you want to, but if you don’t, the internal names are externalized automatically, as if the name had been preceded by #, except for the first parameter. For example, suppose we declare a Dog class like this:

class Dog {

    func say(s:String, times:Int) {

        for _ in 1...times {

            println(s)

        }

    }

}

We didn’t externalize any parameters, but times is not the first parameter, so it is automatically externalized — because this function is a method. Thus, we can make a dog, and then make it bark three times, like this:

let d = Dog()

d.say("woof", times:3)

If, for some reason, you don’t want a method parameter externalized, you can suppress its external name by preceding it with an underscore and a space:

func say(s:String, _ times:Int) {

Now this method would have to be called without labeling the second parameter:

let d = Dog()

d.say("woof", 3)

Overloading

In Swift, function overloading is legal (and common). This means that two functions with exactly the same name and parameter names can coexist as long as they have different signatures.

Thus, for example, these two functions can coexist:

func say (what:String) {

}

func say (what:Int) {

}

This point is particularly striking if you’re coming from Objective-C, where such overloading is not legal. If you tried to declare those two versions of say in Objective-C, you’d get a “Duplicate declaration” compile error. And in fact, if you try to declare those two versions of say in a place where Objective-C can see them (see Appendix A for what that means), you’ll get a Swift compile error — “Method redeclares Objective-C method” — because such overloading is incompatible with Objective-C.

The reason overloading works is that Swift has strict typing. A String is not an Int. Swift can tell them apart in the declaration, and Swift can tell them apart in a function call. Thus, Swift knows unambiguously that say("what") is different from say(1).

It is also legal to have two functions with the same signature but different external parameter names:

func say (what:String) {

}

func say (# what:String) {

}

But that’s not really a case of overloading; the functions have different external parameter names, so they are simply two different functions with two different names.

Overloading works for the return type as well. Two functions with the same name, the same parameter names, and the same parameter types can have different return types. But the context of the call must disambiguate; that is, it must be clear what return type the caller is expecting.

For example, these two functions can coexist (as long as you don’t let Objective-C see them):

func say() -> String {

    return "one"

}

func say() -> Int {

    return 1

}

But now you can’t call say like this:

let result = say() // compile error

The call is ambiguous, and the compiler tells you so. The call must be used in a context where the expected return type is clear. There are many ways to do that. For example, suppose we have another function that is not overloaded, and that expects a String parameter:

func giveMeAString(s:String) {

    println("thanks!")

}

Then giveMeAString(say()) is legal, because only a String can go in this spot, so we must be calling the say that returns a String. Similarly:

let result = say() + "two"

Only a String can be “added” to a String, so this say() must be a String.

Default Parameter Values

A parameter can have a default value. This means that the caller can omit the parameter entirely, supplying no argument for it; the value will then be the default.

To provide a default value, append = and the default value after the parameter type in the declaration:

class Dog {

    func say(s:String, times:Int = 1) {

        for _ in 1...times {

            println(s)

        }

    }

}

Now, if you just want to say something once, you can call say plain and simple, and a times: parameter value of 1 will be supplied for you:

let d = Dog()

d.say("woof") // same as saying d.say("woof", times:1)

If you want repetition, call say(times:):

let d = Dog()

d.say("woof", times:3)

With default parameter values, it’s like getting two functions for the price of one.

A parameter with a default value doesn’t have to have an external name, but by default it does; if you don’t supply one, the internal name is externalized. If you want the external name suppressed, you can suppress it explicitly by preceding the internal name with an underscore and a space. If multiple parameters with default values have a suppressed external name, then unlabeled arguments are applied to them in left-to-right order.

If parameters with external names have default values, the requirement that they be called in order is lifted. For example, if a function at top level is declared like this:

func doThing (a:Int = 0, b:Int = 3) {}

then it is legal to call it like this:

doThing(b:5, a:10)

However, this might be an oversight — with Swift, it’s always hard to know, and certainly it would be illegal to call it like that if either parameter lacked a default value — so I would recommend that you not do that sort of thing: keep your call’s arguments ordered like the parameters in the declaration.

Variadic Parameters

The last (or only) parameter can be variadic. This means that the caller can supply as many values of this parameter’s type as desired, separated by comma; the function body will receive these values as an array.

To indicate that a parameter is variadic, follow it by three dots, like this:

func sayStrings(arrayOfStrings:String ...) {

    for s in arrayOfStrings { println(s) }

}

And here’s how to call it:

sayStrings("hey", "ho", "nonny nonny no")

WARNING

Unfortunately there’s a hole in the Swift language: there’s no way to convert an array into a comma-separated list of arguments (comparable to splatting in Ruby). If what you’re starting with is an array of some type, you can’t use it where a variadic of that type is expected.

Ignored Parameters

A parameter whose local name is an underscore is ignored. The caller must supply an argument, but it has no name within the function body and cannot be referred to there. For example:

func say(s:String, #times:Int, loudly _:Bool) {

No loudly parameter makes its way into the function body, but the caller must still provide the third parameter:

say("hi", times:3, loudly:true)

The declaration needn’t have an externalized name for the ignored parameter:

func say(s:String, #times:Int, _:Bool) {

But the caller must still supply it:

say("hi", times:3, true)

What’s the purpose of this feature? It isn’t to satisfy the compiler, because the compiler doesn’t complain if a parameter is never referred to in the function body. I use it primarily as a kind of note to myself, a way of saying, “Yes, I know there is a parameter here, and I am deliberately not using it for anything.”

Modifiable Parameters

In the body of a function, a parameter is essentially a local variable. By default, it’s a variable implicitly declared with let. You can’t assign to it:

func say(s:String, #times:Int, #loudly:Bool) {

    loudly = true // compile error: Cannot assign to 'let' value 'loudly'

}

If your code needs to assign to a parameter name within the body of a function, declare the parameter name explicitly with var:

func say(s:String, #times:Int, var #loudly:Bool) {

    loudly = true // no problem

}

In that code, the parameter loudly is still just a local variable. Assigning to it doesn’t change the value of any variable outside the function body.

However, it is also possible to configure a parameter in such a way that it does modify the value of a variable outside the function body! One typical use case here is that you want your function to return more than one result. For example, here I’ll write a rather advanced function that removes all occurrences of a given character from a given string and returns the number of occurrences that were removed:

func removeFromString(var s:String, character c:Character) -> Int {

    var howMany = 0

    while let ix = find(s,c) {

        s.removeRange(ix...ix)

        howMany += 1

    }

    return howMany

}

And you call it like this:

let s = "hello"

let result = removeFromString(s, character:Character("l")) // 2

That’s nice, but we forgot one little thing: the original string, s, is still "hello". In the function body, we removed all occurrences of the character parameter from the local copy of the String parameter, but this change didn’t affect the original string.

If we want our function to alter the original value passed to it as a parameter, we must make three changes:

§  The parameter we intend to modify must be declared inout.

§  At the point of the call, the variable holding the value we intend to tell the function to modify must be declared with var, not let.

§  Instead of passing the variable as an argument, we pass its address. This is done by preceding its name with an ampersand (&).

Let’s make those changes. The declaration of removeFromString now looks like this:

func removeFromString(inout s:String, character c:Character) -> Int {

Our call to removeFromString now looks like this:

var s = "hello"

let result = removeFromString(&s, character:Character("l"))

After the call, result is 2 and s is "heo". Notice the ampersand before name of s as the first argument in our function call! I like this requirement, because it forces us to acknowledge explicitly to the compiler, and to ourselves, that we’re about to do something potentially dangerous: we’re letting this function modify a value outside of itself.

TIP

When a function with an inout parameter is called, the variable whose address was passed as argument to that parameter is always set, even if the function makes no changes to that parameter.

You will often encounter variations on this pattern when you’re using Cocoa. The Cocoa APIs are written in C and Objective-C, so you probably won’t see the Swift term inout. You’ll probably see some mysterious type such as UnsafeMutablePointer. From your point of view as the caller, however, it’s the same thing. You’ll prepare a var variable and pass its address.

For instance, consider the Core Graphics function CGRectDivide. A CGRect is a struct representing a rectangle. You call CGRectDivide when you want to slice a rectangle into two rectangles. CGRectDivide needs to tell you what both resulting rectangles are. So it needs to return twoCGRects. Its strategy for doing this is to return no value as a result of the function; instead, it says, “You hand me two CGRects as parameters, and I will modify them for you so that they are the results of this operation.”

Here’s how the declaration for CGRectDivide appears in Swift:

func CGRectDivide(rect: CGRect,

    slice: UnsafeMutablePointer<CGRect>,

    remainder: UnsafeMutablePointer<CGRect>,

    amount: CGFloat,

    edge: CGRectEdge)

The second and third parameters are each an UnsafeMutablePointer to a CGRect. Here’s actual code from one of my apps where I call this function; look at how I treat the second and third parameters (and ignore the others):

var arrow = CGRectZero

var body = CGRectZero

CGRectDivide(rect, &arrow, &body, Arrow.ARHEIGHT, .MinYEdge)

I have to create two var CGRect variables beforehand, and they have to have some value even though that value will immediately be replaced by the call to CGRectDivide, so I assign them CGRectZero as a placeholder.

TIP

Swift extends CGRect to provide a rectsByDividing method. This method, being a Swift method, does something that a Cocoa C function cannot do — it returns two values (as a tuple, see Chapter 3)! Thus, in real life, you could avoid calling CGRectDivide in the first place. Still, you can call CGRectDivide, so it’s worth knowing how to do so.

Sometimes, Cocoa will call your function with an UnsafeMutablePointer parameter, and you will want to change its value. To do this, you cannot assign directly to it, as we did with the inout variable s in our implementation of removeFromString. You’re talking to Objective-C, not to Swift, and this is an UnsafeMutablePointer, not an inout parameter. The technique here is to assign to the UnsafeMutablePointer’s memory property. Here (without further explanation) is an example from my own code:

func popoverPresentationController(

    popoverPresentationController: UIPopoverPresentationController,

    willRepositionPopoverToRect rect: UnsafeMutablePointer<CGRect>,

    inView view: AutoreleasingUnsafeMutablePointer<UIView?>) {

        view.memory = self.button2

        rect.memory = self.button2.bounds

}

There is one very common situation where your function can modify a parameter without declaring it as inout — namely, when the parameter is an instance of a class. This is a special feature of classes, as opposed to the other two object type flavors, enum and struct. String isn’t a class; it’s a struct. That’s why we had to use inout in order to modify a String parameter. So I’ll illustrate by declaring a Dog class with a name property:

class Dog {

    var name = ""

}

Here’s a function that takes a Dog instance parameter and a String, and sets that Dog instance’s name to that String. Notice that no inout is involved:

func changeNameOfDog(d:Dog, to tostring:String) {

    d.name = tostring

}

Here’s how to call it. There’s no inout, so we pass a Dog instance directly:

let d = Dog()

d.name = "Fido"

println(d.name) // "Fido"

changeNameOfDog(d, to:"Rover")

println(d.name) // "Rover"

Observe that we were able to change a property of our Dog instance d, even though it wasn’t passed as an inout parameter, and even though it was declared originally with let, not var. This appears to be an exception to the rules about modifying parameters — but it isn’t really. It’s a feature of class instances, namely that they are themselves mutable. In changeNameOfDog, we didn’t actually attempt to modify the parameter itself. To do that, we would have had to substitute a different Dog instance. That is not what we tried to do, and if we did want to do it, the Dog parameter would need to be declared inout (and d would have to be declared with var and we would have to pass its address as argument).

NOTE

Technically, we say that classes are reference types, whereas the other object type flavors are value types. When you pass an instance of a struct as an argument to a function, you effectively wind up with a separate copy of the struct instance. But when you pass an instance of a class as an argument to a function, you pass a reference to the class instance itself. I’ll discuss this topic in more detail in Chapter 4.

Function In Function

A function can be declared anywhere, including inside the body of a function. A function declared in the body of a function (also called a local function) is available to be called by later code within the same scope, but is completely invisible outside its scope.

This feature is an elegant architecture for functions whose sole purpose is to assist another function. If only function A ever needs to call function B, function B might as well be packaged inside function A.

Here’s a typical example from one of my apps (I’ve omitted everything except the structure):

func checkPair(p1:Piece, and p2:Piece) -> Path? {

    // ...

    func addPathIfValid(midpt1:Point,midpt2:Point) {

        // ...

    }

    for y in -1..._yct {

        addPathIfValid((pt1.x,y),(pt2.x,y))

    }

    for x in -1..._xct {

        addPathIfValid((x,pt1.y),(x,pt2.y))

    }

    // ...

}

What I’m doing in the first for loop (for y) and what I’m doing in the second for loop (for x) are the same — but with a different set of starting values. We could write out the functionality in full inside each for loop, but that would be an unnecessary and confusing repetition. (Such a repetition would violate the principle often referred to as DRY, for “Don’t Repeat Yourself.”) To prevent that repetition, we could refactor the repeated code into an instance method to be called by both for loops, but that exposes publicly an instance method that doesn’t need such broad exposure, as it is called only by these two for loops inside checkPair. A local function is the perfect compromise.

Sometimes, it’s worth using a local function even when that function will be called in only one place. Here’s another example from my code (it’s actually another part of the same function):

func checkPair(p1:Piece, and p2:Piece) -> Path? {

    // ... lots of code here ...

    if arr.count > 0 {

        func distance(pt1:Point, pt2:Point) -> Double {

            // utility to learn physical distance between two points

            let deltax = pt1.0 - pt2.0

            let deltay = pt1.1 - pt2.1

            return sqrt(Double(deltax * deltax + deltay * deltay))

        }

        for thisPath in arr {

            var thisLength = 0.0

            for ix in 0..<(thisPath.count-1) {

                thisLength += distance(thisPath[ix],thisPath[ix+1])

            }

            // ... more code ...

        }

    }

    // ... more code ...

}

Again, the structure is clear (even though the code uses some Swift features I haven’t discussed yet). Deep inside the function checkPair, a moment comes when I have an array (arr) of paths, and I need to know the length of every path. Each path is itself an array of points, so to learn its length, I need to sum the distances between each pair of points. To get the distance between a pair of points, I use the Pythagorean theorem. I could apply the Pythagorean theorem and express the calculation right there inside the for loop (for ix in...). Instead, I’ve expressed it as a separate function, distance, and inside the for loop all I do is call that function.

There is no savings whatever in the number of lines of code; in fact, declaring distance makes my code longer! Nor, strictly speaking, am I in danger of repeating myself; the application of the Pythagorean theorem is repeated many times, but it occurs at only one spot in my code, namely inside this one for loop. Nevertheless, abstracting the code into a more general distance-calculation utility makes my code much clearer: in effect, I announce in general form what I’m about to do (“Look! I’m going to calculate distances between points now!”), and then I do it. The function name, distance, gives my code meaning; it is more understandable and maintainable than if I had directly written out the steps of the distance calculation inline.

Recursion

A function can call itself. This is called recursion. Recursion seems a little scary, rather like jumping off a cliff, because there seems to be a danger of creating an infinite loop; but if you write the function correctly, you will always have a “stopper” condition that handles the degenerate case and prevents the loop from being infinite:

func countDownFrom(ix:Int) {

    println(ix)

    if ix > 0 { // stopper

        countDownFrom(ix-1) // recurse!

    }

}

Swift imposes a restriction on recursion: a function-in-function (a local function) must not call itself. In practice, this restriction will not prove onerous; just put the function at a higher level, such as the top level of the surrounding object declaration or the top level of the file.

Function As Value

If you’ve never used a programming language where functions are first-class citizens, perhaps you’d better sit down now, because what I’m about to tell you might make you feel a little faint: In Swift, a function is a first-class citizen. This means that a function can be used wherever a value can be used. For example, a function can be assigned to a variable; a function can be passed as an argument in a function call; a function can be returned as the result of a function.

Swift has strict typing. You can only assign a value to a variable or pass a value into or out of a function if it is the right type of value. In order for a function to be used as a value, it needs to have a type. And indeed it does! Have you guessed what it is? A function’s signature is its type.

The chief purpose of using a function as a value is so that this function can later be called without a definite knowledge of what function it is.

Here’s the world’s simplest (and silliest) example, just to show the syntax and structure:

func doThis(f:()->()) {

    f()

}

That is a function doThis that takes one parameter (and returns no value). The parameter, f, is itself a function; we know this because the type of the parameter is not given as Int or String or Dog, but is a function signature, ()->(), meaning (as you know) a function that takes no parameters and returns no value. The function doThis then calls the function f that it received as its parameter — that (as you know) is the meaning of the parentheses after the name of the parameter in the function body.

How would you call the function doThis? To do so, you’d need to pass it a function as argument. One way to do that is to use the name of a function as the argument, like this:

func whatToDo() {

    println("I did it")

}

doThis(whatToDo)

First, we declare a function of the proper type — a function that takes no parameters and returns no value. Then, we call doThis, passing as argument the name of the function. Notice that we are not calling whatToDo here; we are passing it. Sure enough, this works: we pass whatToDo as argument to doThis; doThis calls the function that it receives as its parameter; and the string "I did it" appears in the console.

But what’s the point of being able to do that? If our goal is to call whatToDo, why don’t we just call it? What’s useful about being able to tell some other function to call it? In the example I just gave, there is nothing useful about it; I was just showing you the syntax and structure. But in real life, this is a very valuable thing to do, because the other function may call the parameter function in some special way. For example, it might call it after doing other things, or at some later time.

For example, one reason for encapsulating function-calling in a function is that it can reduce repetition and opportunity for error. Here’s a case from my own code. A common thing to do in Cocoa is to draw an image, directly, in code. This involves four steps:

let size = CGSizeMake(15,15)

UIGraphicsBeginImageContextWithOptions(size, false, 0) 1

let p = UIBezierPath(

    roundedRect: CGRectMake(0,0,15,15), cornerRadius: 8)

p.stroke() 2

let result = UIGraphicsGetImageFromCurrentImageContext() 3

UIGraphicsEndImageContext() 4

1

Open an image context.

2

Draw into the context.

3

Extract the image.

4

Close the image context.

That’s terribly ugly. The sole purpose of all that code is to obtain result, the image; but that purpose is buried in all the other code. At the same time, the entire structure is boilerplate; every time I do this in any app, step 1, step 3, and step 4 are exactly the same. Moreover, I live in mortal fear of forgetting a step; for example, if I were to omit step 4 by mistake, the universe would explode.

The only thing that’s different every time I draw is step 2. Thus, step 2 is the only part I should have to write out! The entire problem is solved by writing a utility function expressing the boilerplate:

func imageOfSize(size:CGSize, whatToDraw:() -> ()) -> UIImage {

    UIGraphicsBeginImageContextWithOptions(size, false, 0)

    whatToDraw()

    let result = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()

    return result

}

My imageOfSize utility is so useful that I declare it at the top level of a file, where all my files can see it. Thus, by default, none of its parameters have external names. To make an image, I perform step 2 (the actual drawing) in a function and pass that function as argument to theimageOfSize utility:

func drawing() {

    let p = UIBezierPath(

        roundedRect: CGRectMake(0,0,15,15), cornerRadius: 8)

    p.stroke()

}

let image = imageOfSize(CGSizeMake(15,15), drawing)

Now that is a beautifully expressive and clear way to turn drawing instructions into an image.

The Cocoa API is full of situations where you’ll pass a function to be called by the runtime in some special way or at some later time. For example, when one view controller presents another, the method you’ll call takes three parameters — the view controller to be presented; a Bool stating whether you want the presentation to be animated; and a function that is to be called after the presentation has finished:

let vc = UIViewController()

func whatToDoLater() {

    println("I finished!")

}

self.presentViewController(vc, animated:true, completion:whatToDoLater)

The Cocoa documentation will often describe such a function as a handler, and will refer it as a block, because that’s the Objective-C syntactic construct needed here; in Swift, it’s a function, so just think of it as a function and pass a function.

Some common Cocoa situations even involve passing two functions to a function. For instance, when you perform view animation, you’ll often pass one function prescribing the action to be animated and another function saying what to do afterwards:

func whatToAnimate() { // self.myButton is a button in the interface

    self.myButton.frame.origin.y += 20

}

func whatToDoLater(finished:Bool) {

    println("finished: \(finished)")

}

UIView.animateWithDuration(

    0.4, animations: whatToAnimate, completion: whatToDoLater)

That means: Change the frame origin (that is, the position) of this button in the interface, but do it over time (four-tenths of a second); and then, when that’s finished, print a log message in the console saying whether the animation was performed or not.

TIP

To make function type specifiers clearer, take advantage of Swift’s typealias feature to create a type alias giving a function type a name. The name can be descriptive, and the possibly confusing arrow operator notation is avoided. For example, if you say typealias VoidVoidFunction = () -> (), you can then say VoidVoidFunction wherever you need to specify a function type with that signature.

Anonymous Functions

Consider again the preceding example:

func whatToAnimate() { // self.myButton is a button in the interface

    self.myButton.frame.origin.y += 20

}

func whatToDoLater(finished:Bool) {

    println("finished: \(finished)")

}

UIView.animateWithDuration(

    0.4, animations: whatToAnimate, completion: whatToDoLater)

There’s a slight bit of ugliness in that code. I’m declaring functions whatToAnimate and whatToDoLater, just because I want to pass those functions in the last line. I don’t really need the names whatToAnimate and whatToDoLater for anything, except to refer to them in the last line; neither the names nor the functions will ever be used again. Therefore, it would be nice to be able to pass just the body of those functions without a declared name.

That’s called an anonymous function, and it’s legal and common in Swift. To form an anonymous function, you do two things:

1.    Create the function body itself, including the surrounding curly braces, but with no function declaration.

2.    If necessary, express the function’s parameter list and return type as the first line inside the curly braces, followed by the keyword in.

Let’s practice by transforming our named function declarations into anonymous functions. Here’s the named function declaration for whatToAnimate:

func whatToAnimate() {

    self.myButton.frame.origin.y += 20

}

Here’s an anonymous function that does the same thing. Notice how I’ve moved the parameter list and return type inside the curly braces:

{

    () -> () in

    self.myButton.frame.origin.y += 20

}

Here’s the named function declaration for whatToDoLater:

func whatToDoLater(finished:Bool) {

    println("finished: \(finished)")

}

Here’s an anonymous function that does the same thing:

{

    (finished:Bool) -> () in

    println("finished: \(finished)")

}

Now that we know how to make anonymous functions, let’s use them. In our call to animateWithDuration, the point where we need the functions is the point where we’re passing arguments to animateWithDuration. We can create and pass anonymous functions right at that point, like this:

UIView.animateWithDuration(0.4, animations: {

    () -> () in

    self.myButton.frame.origin.y += 20

    }, completion: {

        (finished:Bool) -> () in

        println("finished: \(finished)")

})

Anonymous functions are very commonly used in Swift, so make sure you can read and write that code! Anonymous functions, in fact, are so common and so important, that some shortcuts for writing them are provided:

Omission of the return type

If the anonymous function’s return type is known to the compiler, you can omit the arrow operator and the specification of the return type:

UIView.animateWithDuration(0.4, animations: {

    () in

    self.myButton.frame.origin.y += 20

    }, completion: {

        (finished:Bool) in

        println("finished: \(finished)")

})

Omission of the in line when there are no parameters

If the anonymous function takes no parameters, and if the return type can be omitted, the in line itself can be omitted entirely:

UIView.animateWithDuration(0.4, animations: {

    self.myButton.frame.origin.y += 20

    }, completion: {

        (finished:Bool) in

        println("finished: \(finished)")

})

Omission of the parameter types

If the anonymous function takes parameters and their types are known to the compiler, the types can be omitted:

UIView.animateWithDuration(0.4, animations: {

    self.myButton.frame.origin.y += 20

    }, completion: {

        (finished) in

        println("finished: \(finished)")

})

Omission of the parentheses

If the parameter types are omitted, the parentheses around the parameter list can be omitted:

UIView.animateWithDuration(0.4, animations: {

    self.myButton.frame.origin.y += 20

    }, completion: {

        finished in

        println("finished: \(finished)")

})

Omission of the in line even when there are parameters

If the return type can be omitted, and if the parameter types are known to the compiler, you can omit the in line and refer to the parameters directly within the body of the anonymous function by using the magic names $0, $1, and so on, in order:

UIView.animateWithDuration(0.4, animations: {

    self.myButton.frame.origin.y += 20

    }, completion: {

        println("finished: \($0)")

})

Omission of the parameter names

If your anonymous function body doesn’t need the parameters, you can ignore the parameters by substituting an underscore for their names in the in line:

UIView.animateWithDuration(0.4, animations: {

    self.myButton.frame.origin.y += 20

    }, completion: {

        _ in

        println("finished!")

})

TIP

But note that if the anonymous function takes parameters, you must use them somehow. You can omit the in line and use the parameters by the magic names $0 and so on, or you can keep the in line and ignore the parameters with underscores, but you can’t omit the in line altogether and not use the parameters by their magic names! If you do, your code won’t compile — and the error message that Swift gives you will be very, very confusing.

Omission of the calling function parameter name

If, as will just about always by case, your anonymous function is the last parameter being passed in this function call, you can close the function call with a right parenthesis before this last parameter, and then put just the anonymous function body without any parameter name (this is called a trailing function):

UIView.animateWithDuration(0.4, animations: {

    self.myButton.frame.origin.y += 20

    }) {

        _ in

        println("finished!")

}

Omission of the calling function parentheses

If you use the trailing function syntax, and if the function you are calling takes no parameters other than the function you are passing to it, you can omit the empty parentheses from the call. To illustrate, I’ll declare and call a different function:

func doThis(f:()->()) {

    f()

}

doThis { // no parentheses!

    println("Howdy")

}

This is the only situation in which you can omit the parentheses from a function call!

Omission of the keyword return

If the anonymous function body consists of exactly one statement and that statement consists of returning a value with the keyword return, the keyword return can be omitted. To put it another way, in a context that expects a function that returns a value, if an anonymous function body consists of exactly one statement, Swift assumes that this statement is an expression whose value is to be returned from the anonymous function:

func sayHowdy() -> String {

    return "Howdy"

}

func performAndPrint(f:()->String) {

    let s = f()

    println(s)

}

performAndPrint {

    sayHowdy() // meaning: return sayHowdy()

}

When writing anonymous functions, you will frequently find yourself taking advantage of all the omissions you are permitted. In addition, you’ll often shorten the layout of the code (though not the code itself) by putting the whole anonymous function together with the function call on one line. Thus, Swift code involving anonymous functions can be extremely compact.

Here’s a typical example. We start with an array of Int values and generate a new array consisting of all those values multiplied by 2, by calling the map instance method. The map method of an array takes a function that takes one parameter, and returns a value, of the same type as the array’s elements; here, our array is made of Int values, so we need to pass to the map method a function that takes one Int parameter and returns an Int. We could write out the whole function, like this:

let arr = [2, 4, 6, 8]

func doubleMe(i:Int) -> Int {

    return i*2

}

let arr2 = arr.map(doubleMe) // [4, 8, 12, 16]

That, however, is not very Swifty. We don’t need the name doubleMe for anything else, so this may as well be an anonymous function. Its return type is known, so we don’t need to specify that. Its parameter type is known, so we don’t need to specify that. There’s just one parameter and we are going to use it, so we don’t need the in line as long we refer to the parameter as $0. Our function body consists of just one statement, and it is a return statement, so we can omit return. And map doesn’t take any other parameters, so we can omit the parentheses and follow the name directly with the anonymous function parameter:

let arr = [2, 4, 6, 8]

let arr2 = arr.map {$0*2}

Define-and-Call

A pattern that’s surprisingly common in Swift is to define an anonymous function and call it, all in one move:

{

    // ... code goes here

}()

Why would anyone do such a thing? If you want to run some code, you can just run it; why would you embed it in a deeper level as a function body, only to turn around and run that function body immediately?

I sometimes do this as a way of defining a deeper scope inside a function body. A deeper scope can be useful, for example, when you want to declare some local variables that you don’t need elsewhere in the surrounding function. Unlike C, Swift won’t let you arbitrarily create a deeper scope with curly braces; but it will let you define and call an anonymous local function:

func myFunc() {

    // ... some code here ...

    {

        () -> () in

        // ... this is a deeper scope ...

    }()

    // ... more code here ...

}

(You might have to put a semicolon at the end of the previous line, so that Swift doesn’t think this is a trailing function.)

Also, an anonymous function can be a good way to make your code less imperative and more, well, functional: an action can be taken at the point where it is needed, rather than in a series of preparatory steps. Here’s a common Cocoa example: we create and configure an NSMutableParagraphStyle and then use it in a call to addAttribute:value:range: (content is an NSMutableAttributedString):

let para = NSMutableParagraphStyle()

para.headIndent = 10

para.firstLineHeadIndent = 10

// ... more configuration of para ...

content.addAttribute(

    NSParagraphStyleAttributeName,

    value:para, range:NSMakeRange(0,1))

I find that code ugly. We don’t need para except to pass it as the value: argument within the call to addAttribute:..., so it would be much nicer to create and configure it right there within the call to addAttribute:.... Swift lets us do just that. I much prefer this way of writing the same code:

content.addAttribute(

    NSParagraphStyleAttributeName,

    value: {

        let para = NSMutableParagraphStyle()

        para.headIndent = 10

        para.firstLineHeadIndent = 10

        // ... more configuration of para ...

        return para

    }(),

    range:NSMakeRange(0,1))

Closures

Swift functions are closures. This means they can capture references to external variables in scope within the body of the function. What do I mean by that? Well, recall from Chapter 1 that code in curly braces constitutes a scope, and this code can “see” variables and functions declared in a surrounding scope:

class Dog {

    var whatADogSays = "woof"

    func bark() {

        println(self.whatADogSays)

    }

}

In that code, the body of the function bark refers to a variable whatADogSays that is declared outside the body of the function. It is in scope for the body of the function — the code inside the body of bark can see whatADogSays, and makes an explicit reference to it.

So far, so good; but we now know that the function bark can be passed as a value. In effect, it can travel from one environment to another! When it does, what happens to that reference to whatADogSays? Let’s find out:

func doThis(f : Void -> Void) {

    f()

}

let d = Dog()

doThis(d.bark) // woof

We run that code, and "woof" appears in the console. Perhaps that result doesn’t seem very surprising to you. But think about it. We do not directly call bark. We make a Dog instance and pass its bark function as a value into the function doThis. There, it is called. Now, whatADogSaysis an instance property of a particular Dog. Inside the function doThis there no whatADogSays. Indeed, inside the function doThis there is no Dog instance! Nevertheless the call f() still works. The function d.bark, as it is passed around, can still see that variable whatADogSays, declared outside itself, even though it is called in an environment where there is no longer any Dog instance and no longer any instance property whatADogSays.

The bark function, it appears, is carrying its original whatADogSays reference with it — even when bark isn’t called until it has been passed into some other environment entirely. So, by “capture” I mean that when a function is passed around as a value, it carries with it any variables outside itself that it refers to inside itself. That is what makes a function a closure.

You’ll probably take advantage of the fact that functions are closures without even being conscious of it. Recall this earlier example, where we animate the repositioning of a button in our interface:

UIView.animateWithDuration(0.4, animations: {

    self.myButton.frame.origin.y += 20

    }) {

        _ in

        println("finished!")

}

It seems innocent enough; but concentrate on the second line, the anonymous function passed as argument to the animations: parameter. You should be saying: Really? Way off in the land of Cocoa, when this anonymous function is executed at some future time to start the animation, Cocoa is going to be able to find myButton, an object referred to as a property of self, way back over here in my code? Yes, Cocoa will be able to do that, because a function is a closure. The reference to this property is captured and maintained by the anonymous function; thus, when the anonymous function is actually called, it works and the button moves.

How Closures Improve Code

Once you understand that functions are closures, you can start writing your own code that takes advantage of this fact to improve your code’s syntax. Closures can help make your code more general, and hence more useful. For instance, recall my earlier example of a function that takes drawing instructions and performs them to generate an image:

func imageOfSize(size:CGSize, whatToDraw:() -> ()) -> UIImage {

    UIGraphicsBeginImageContextWithOptions(size, false, 0)

    whatToDraw()

    let result = UIGraphicsGetImageFromCurrentImageContext()

    UIGraphicsEndImageContext()

    return result

}

Earlier, we called that function like this:

func drawing() {

    let p = UIBezierPath(

        roundedRect: CGRectMake(0,0,15,15), cornerRadius: 8)

    p.stroke()

}

let image = imageOfSize(CGSizeMake(15,15), drawing)

We now know, however, that we don’t need to declare the drawing function separately. We can call imageOfSize with an anonymous function:

let image = imageOfSize(CGSizeMake(15,15)) {

    let p = UIBezierPath(

        roundedRect: CGRectMake(0,0,15,15), cornerRadius: 8)

    p.stroke()

}

That’s much neater. There remains, however, an annoying repetition. This is a call to create an image of a given size consisting of a rounded rectangle of that size. We are repeating the size; the pair of numbers 15,15 appears twice. That’s silly. Let’s prevent the repetition by putting the size into a variable at the outset:

let sz = CGSizeMake(15,15)

let image = imageOfSize(sz) {

    let p = UIBezierPath(

        roundedRect: CGRect(origin:CGPointZero, size:sz), cornerRadius: 8)

    p.stroke()

}

The variable sz, declared outside our anonymous function at a higher level, is visible inside it. Thus we can refer to it inside the anonymous function — and we do so. The anonymous function is a function. Therefore it is a closure. Therefore the anonymous function captures that reference, and carries it on into the call to imageOfSize. When imageOfSize calls whatToDraw and whatToDraw refers to a variable sz, there’s no problem, even though there is no sz anywhere in the neighborhood of imageOfSize.

Now let’s go further. So far, we’ve been hard-coding the size of the desired rounded rectangle. Imagine, though, that creating images of rounded rectangles of various sizes is something we do often. It would make sense to package this code up as a function, where sz is not a fixed value but a parameter; the function will then return the image:

func makeRoundedRectangle(sz:CGSize) -> UIImage {

    let image = imageOfSize(sz) {

        let p = UIBezierPath(

            roundedRect: CGRect(origin:CGPointZero, size:sz),

            cornerRadius: 8)

        p.stroke()

    }

    return image

}

Observe that our code still works. Here, sz in the anonymous function refers to the sz parameter that arrives into the surrounding function makeRoundedRectangle. A parameter of the surrounding function is a variable external to and in scope within the anonymous function. The anonymous function is a closure, so it captures the reference to that parameter.

Our code is becoming beautifully compact. To call makeRoundedRectangle, supply a size; an image is returned. Thus, I can perform the call, obtain the image, and put that image into my interface, all in one move, like this:

self.myImageView.image = makeRoundedRectangle(CGSizeMake(45,20))

Function Returning Function

But now let’s go even further! Instead of returning an image, our function can return a function that makes rounded rectangles of the specified size. If you’ve never seen a function returned as a value from a function, you may now be gasping for breath. But a function, after all, can be used as a value. We have already passed a function into a function as an argument; now we are going to receive a function from a function call as its result:

func makeRoundedRectangleMaker(sz:CGSize) -> () -> UIImage { 1

    func f () -> UIImage { 2

        let im = imageOfSize(sz) {

            let p = UIBezierPath(

                roundedRect: CGRect(origin:CGPointZero, size:sz),

                cornerRadius: 8)

            p.stroke()

        }

        return im

    }

    return f 3

}

Let’s analyze that code slowly:

1

The declaration is the hardest part. What on earth is the type (signature) of this function makeRoundedRectangleMaker? It is (CGSize) -> () -> UIImage. That expression has two arrow operators. To understand it, keep in mind that everything after each arrow operator is the type of a returned value. So makeRoundedRectangleMaker is a function that takes a CGSize parameter and returns a () -> UIImage. Okay, and what’s a () -> UIImage? We already know that: it’s a function that takes no parameters and returns a UIImage (an image). SomakeRoundedRectangleMaker is a function that takes a CGSize parameter and returns a function — a function that itself, when called with no parameters, will return a UIImage.

2

Now here we are in the body of the function makeRoundedRectangleMaker, and our first step is to declare a function (a function-in-function, or local function) of precisely the type we intend to return, namely, one that takes no parameters and returns a UIImage. Here, we’re naming this function f. The way this function works is simple and familiar: it calls imageOfSize, passing it an anonymous function that makes an image of a rounded rectangle (im) — and then it returns the image.

3

Finally, we return the function we just made (f). We have thus fulfilled our contract: we said we would return a function that takes no parameters and returns a UIImage, and we do so.

But perhaps you are still gazing open-mouthed at makeRoundedRectangleMaker, wondering how you would ever call it and what you would get if you did. Let’s try it:

let maker = makeRoundedRectangleMaker(CGSizeMake(45,30))

What is the variable maker after that code runs? It’s a function — a function that takes no parameters and that, when called, produces the image of a rounded rectangle of size 45,30. You don’t believe me? I’ll prove it — by calling the function that is now the value of maker:

let maker = makeRoundedRectangleMaker(CGSizeMake(45,30))

self.myImageView.image = maker()

Now that you’ve gotten over your stunned surprise at the notion of a function that produces a function as its result, turn your attention once again to the implementation of makeRoundedRectangleMaker and let’s analyze it again, a different way. Remember, I didn’t write that function to show you that a function can produce a function. I wrote it to illustrate closures! Let’s think about how the environment gets captured:

func makeRoundedRectangleMaker(sz:CGSize) -> () -> UIImage {

    func f () -> UIImage {

        let im = imageOfSize(sz) { // *

            let p = UIBezierPath(

                roundedRect: CGRect(origin:CGPointZero, size:sz), // *

                cornerRadius: 8)

            p.stroke()

        }

        return im

    }

    return f

}

The function f takes no parameters. Yet, twice within the function body of f (I’ve marked the places with asterisk comments), there are references to a size value sz. The body of the function f can see sz, the incoming parameter to the surrounding functionmakeRoundedRectangleMaker, because it is in a surrounding scope. The function f captures the reference to sz at the time makeRoundedRectangleMaker is called, and keeps that reference when f is returned and assigned to maker:

let maker = makeRoundedRectangleMaker(CGSizeMake(45,30))

That is why maker is now a function that, when it is called, creates and returns an image of the particular size 45,30 even though it itself will be called with no parameters. We have baked the knowledge of what size of image to produce into maker.

Looking at it another way, makeRoundedRectangleMaker is a factory for creating a whole family of functions similar to maker, each of which produces an image of one particular size. That’s a dramatic illustration of the power of closures.

Before I leave makeRoundedRectangleMaker, I’d like to rewrite it in a Swiftier fashion. Within f, there is no need to create im and then return it; we can return the result of calling imageOfSize directly:

func makeRoundedRectangleMaker(sz:CGSize) -> () -> UIImage {

    func f () -> UIImage {

        return imageOfSize(sz) {

            let p = UIBezierPath(

                roundedRect: CGRect(origin:CGPointZero, size:sz),

                cornerRadius: 8)

            p.stroke()

        }

    }

    return f

}

But there is no need to declare f and then return it either; it can be an anonymous function and we can return it directly:

func makeRoundedRectangleMaker(sz:CGSize) -> () -> UIImage {

    return {

        return imageOfSize(sz) {

            let p = UIBezierPath(

                roundedRect: CGRect(origin:CGPointZero, size:sz),

                cornerRadius: 8)

            p.stroke()

        }

    }

}

But our anonymous function consists of just one statement, returning the result of the call to imageOfSize. (The anonymous function parameter to imageOfSize is written over multiple lines, but the imageOfSize call itself is still just one Swift statement.) Thus there is no need to sayreturn:

func makeRoundedRectangleMaker(sz:CGSize) -> () -> UIImage {

    return {

        imageOfSize(sz) {

            let p = UIBezierPath(

                roundedRect: CGRect(origin:CGPointZero, size:sz),

                cornerRadius: 8)

            p.stroke()

        }

    }

}

Closure Setting a Captured Variable

The power that a closure gets through its ability to capture its environment is even greater than I’ve shown so far. If a closure contains a reference to a variable outside itself, and if that variable is settable, the closure can set the variable.

For example, at the top level of my Swift file I’ve declared this simple function. All it does is to accept a function that takes an Int parameter, and to call that function with an argument of 100:

func pass100 (f:(Int)->()) {

    f(100)

}

Now, look closely at this code and try to guess what will happen when we run it:

var x = 0

println(x)

func setX(newX:Int) {

    x = newX

}

pass100(setX)

println(x)

The first println call obviously produces 0. The second println call produces 100! The pass100 function has reached into my code and changed the value of my variable x! That’s because the function that I passed to pass100 contains a reference to x; not only does it contain it, but it captures it; not only does it capture it, but it sets its value. That x is my x. Thus, pass100 was able to set my x just as readily as I would have set it by calling setX directly.

Closure Preserving Its Captured Environment

When a closure captures its environment, it preserves that environment even if nothing else does. Here’s an example calculated to blow your mind — a function that modifies a function:

func countAdder(f:()->()) -> () -> () {

    var ct = 0

    return {

        ct = ct + 1

        println("count is \(ct)")

        f()

    }

}

The function countAdder accepts a function as its parameter and returns a function as its result. The function that it returns calls the function that it accepts, with a little bit added: it increments a variable and reports the result. So now try to guess what will happen when we run this code:

func greet () {

    println("howdy")

}

let countedGreet = countAdder(greet)

countedGreet()

countedGreet()

countedGreet()

What we’ve done here is to take a function greet, which prints "howdy", and pass it through countAdder. What comes out the other side of countAdder is a new function, which we’ve named countedGreet. We then call countedGreet three times. Here’s what appears in the console:

count is 1

howdy

count is 2

howdy

count is 3

howdy

Clearly, countAdder has added to the functionality of the function that was passed into it the ability to report how many times it is called. Now ask yourself: Where on earth is the variable that maintains this count? Inside countAdder, it was a local variable ct. But it isn’t declared inside the anonymous function that countAdder returns. That’s deliberate! If it were declared inside the anonymous function, we would be setting ct to 0 every time countedGreet is called — we wouldn’t be counting. Instead, ct is initialized to 0 once and then captured by the anonymous function. Thus, this variable is preserved as part of the environment of countedGreet — it is outside countedGreet in some mysterious environment-preserving world, so that it can be incremented every time countedGreet is called. That’s the power of closures.

That example, with its maintenance of environmental state, can also help us to demonstrate that functions are reference types. To show what I mean, I’ll start with a contrasting situation. Two separate calls to a function factory method produce two different functions, as you would expect:

let countedGreet = countAdder(greet)

let countedGreet2 = countAdder(greet)

countedGreet() // count is 1

countedGreet2() // count is 1

The two functions countedGreet and countedGreet2, in that code, are maintaining their counts separately. But mere assignment or parameter passing results in a new reference to the same function:

let countedGreet = countAdder(greet)

let countedGreet2 = countedGreet

countedGreet() // count is 1

countedGreet2() // count is 2

Curried Functions

Return once more to makeRoundedRectangleMaker:

func makeRoundedRectangleMaker(sz:CGSize) -> () -> UIImage {

    return {

        imageOfSize(sz) {

            let p = UIBezierPath(

                roundedRect: CGRect(origin:CGPointZero, size:sz),

                cornerRadius: 8)

            p.stroke()

        }

    }

}

There’s something I don’t like about this method: the size of the rounded rectangle that it creates is a parameter (sz), but the cornerRadius of the rounded rectangle is hard-coded as 8. I’d like the ability to specify a value for the corner radius as well. I can think of two ways to do it. One is to give makeRoundedRectangleMaker itself another parameter:

func makeRoundedRectangleMaker(sz:CGSize, rad:CGFloat) -> () -> UIImage {

    return {

        imageOfSize(sz) {

            let p = UIBezierPath(

                roundedRect: CGRect(origin:CGPointZero, size:sz),

                cornerRadius: rad)

            p.stroke()

        }

    }

}

And we would then call it like this:

let maker = makeRoundedRectangleMaker(CGSizeMake(45,30), rad:20)

But there’s another way. The function that we are returning from makeRoundedRectangleMaker takes no parameters. Instead, it could take the extra parameter:

func makeRoundedRectangleMaker(sz:CGSize) -> (CGFloat) -> UIImage {

    return {

        rad in

        imageOfSize(sz) {

            let p = UIBezierPath(

                roundedRect: CGRect(origin:CGPointZero, size:sz),

                cornerRadius: rad)

            p.stroke()

        }

    }

}

Now makeRoundedRectangleMaker returns a function that, itself, takes one parameter, so we must remember to supply that when we call it:

let maker = makeRoundedRectangleMaker(CGSizeMake(45,30))

self.myImageView.image = maker(14)

If we don’t need to conserve maker for anything, we can of course do all that in one line — a function call that yields a function which we immediately call:

self.myImageView.image = makeRoundedRectangleMaker(CGSizeMake(45,30))(14)

When a function returns a function that takes a parameter in this way, it is called a curried function (not because of the food or because of a horse comb, but after the computer scientist Haskell Curry).

It turns out that there’s a Swift shorthand for writing the declaration of a curried function. You can omit the first arrow operator and the top-level anonymous function, like this:

func makeRoundedRectangleMaker(sz:CGSize)(rad:CGFloat) -> UIImage {

    return imageOfSize(sz) {

        let p = UIBezierPath(

            roundedRect: CGRect(origin:CGPointZero, size:sz),

            cornerRadius: rad)

        p.stroke()

    }

}

The expression (sz:CGSize)(rad:CGFloat) — two parameter lists in a row, with no arrow operator between them — means “Swift, please curry this function for me.” Swift here does all the work of dividing our function into two functions, one (makeRoundedRectangleMaker) taking a CGSize parameter and another (the anonymous result) taking a CGFloat. Our code looks as if makeRoundedRectangleMaker returns a UIImage, but it actually returns a function that returns a UIImage just as before. And we can call it in basically just the same two ways as before; in two stages, like this:

let maker = makeRoundedRectangleMaker(CGSizeMake(45,30))

self.myImageView.image = maker(rad:14)

Or in a single line, like this:

self.myImageView.image =

    makeRoundedRectangleMaker(CGSizeMake(45,30))(rad:14)