Closure (or block in objective-c) is a very interesting construct in software engineering. It defines a block of functionality that can be passed around and invoked in a later time.

What makes it even more interesting is that they store references to constants and variables that are accessible to its context. The variables and constants captured in a closure are shared among all the closures that captured the same variables.

These captured variables become, in a way, a shared state between the closures that captured it. Each of the capturing closure will have access to read and modify these captured variables.

Lets check this behaviour in an example:

var x = 1

let increment = {  
  x += 1
}

let decrement = {  
  x -= 1
}

let getNumber = {  
  return x
}

let setNumber = { newX in  
  x = newX
}

Here we implemented a counter by defining a variable x, which has the current state of the counter, a setter setNumber and a getter getNumber, and two mutating methods.

Each of these closures will be able to read and modify the value of x.

Calling increment and decrement alters the value of x:

print(getNumber())  
increment()  
print(getNumber())  
decrement()  
print(getNumber())  
setNumber(20)  
print(getNumber())  

The above procedure prints the following:

1  
2  
1  
20  

As we saw from the execution, variable x represents our counter current state. In this particular example, the state is an integer, however, we can choose any type to represent our state (such as a tuple, struct or class).

The value of x gets modified when calling increment, decrement and setNumber. The modification gets shared between consequent closure calls.

The above counter behaviour can be mapped to an object oriented model:

  • x represent the state of our instances; which makes it an instance variable.
  • x initial value of 1 is set in the object constructor.
  • the closures represent the behaviour of the object; which makes them the instance methods.
  • getNumber and setNumber are the getter and the setter of the instance variable.

Following the above breakdown, lets convert our counter closure implementation to a class:

class Counter {  
  private var x: Int

  init(number: Int) {
    x = number
  }

  func setNumber(_ number: Int) {
    x = number
  }

  func getNumber() -> Int {
    return x
  }

  func increment() {
    x += 1
  }

  func decrement() {
    x -= 1
  }
}

Now that it's a class, we call it like this:

let c = Counter(number: 1)  
print(c.getNumber())  
c.increment()  
print(c.getNumber())  
c.decrement()  
print(c.getNumber())  
c.setNumber(20)  
print(c.getNumber())  

this outputs similar to the closure counter implementation.


Pushing the closures further

We saw above two implementation of a counter; as a variable with a set of closures, and as a class. Both the implementation are very similar.

One major criticism on the closure implementation is that it's not self contained; there is no way to create a counter and share it around, the only way to share the behaviour of the counter is by sharing the 4 closures separately.

What we would like to have is a way to create our counter (using the closures) in a self contained way. That will allow us to create multiple counters, and will allow us to share the counter and reuse them in different parts of our code.

In other words, what we want is to use a function and closures to implement something that looks similar to the previous Counter class.

To create a self-contained counter closure implementation, lets start by defining what does our counter consist of; Our closure counter behaviour is defined by 4 closures and a simple int state.

These 4 closures and their types are:

let increment: () -> ()  
let decrement: () -> ()  
let getNumber: () -> Int  
let setNumber: (Int) -> ()  

We can type alias them for better readability to the following:

typealias Getter = () -> Int  
typealias Setter = (Int) -> ()  
typealias Mutators = () -> ()  

In order to be able to create a counter at will, we define a function that contains a local integer variable (variable x from our initial implementation), and creates and return the four closures.

This function body will contain the following instructions:

var x = SomeInitialValue

let getNumber = { return x }  
let setNumber = { x = $0 }  
let increment = { x += 1 }  
let decrement = { x -= 1 }

// Return the closures somehow.

The biggest challenge here is to define the signature of this function. Remember our goal here is to recreate the Counter class example by using a function and a set of closures. So we want to be able to call this function in a way that it looks like we are calling the Counter class; let c = Counter(number: 1).

That leaves us with this function signature:

func Counter(number initial: Int) -> SomethingHere {  
  // Function Body
}

Next, we need to figure out the return type of this function (SomethingHere).

Since we want this function to look like the Counter class. The function should return a type that contains at least the 4 original methods of Counter (getNumber, setNumber, increment and decrement)

c.getNumber()  
c.increment()  
c.getNumber()  
c.decrement()  
c.setNumber(20)  

c here has SomethingHere type; which is the type that the Counter function returned.

One way of having c contain the attributes above, is for c to be a named tuple; with the desired function names as labels and the function closures as values.

Our function definition should look like this now:

func Counter(number initial: Int) -> (getNumber: Getter, setNumber: Setter, increment: Mutators, decrement: Mutators) {  
}

The tuple has labels that match the name of the method in the class implementation of Counter. The type of these labels also matches the methods of Counter (which we defined in the type aliases above).

Now that we have the function signature and the body, lets join them together:

func Counter(number initial: Int) -> (getNumber: Getter, setNumber: Setter, increment: Mutators, decrement: Mutators) {  
  var x = initial

  let getNumber = { return x }
  let setNumber = { x = $0 }
  let increment = { x += 1 }
  let decrement = { x -= 1 }

  return (
    getNumber: getNumber,
    setNumber: setNumber,
    increment: increment,
    decrement: decrement)
}

To confirm that we have a working example, we can try using this Counter function as if it was an object.

let c = Counter(number: 1)  
print(c.getNumber())  
c.increment()  
print(c.getNumber())  
c.decrement()  
print(c.getNumber())  
c.setNumber(20)  
print(c.getNumber())  

this prints the same output it did with the class implementation.

1  
2  
1  
20  

When we call Counter() method, it returns a tuple with the 4 closures we defined. Since these closures are defined in the same lexical context, they all share the same context variable, which is x in this case.

Each of these 4 closures have read and modify access to x. Moreover, any alteration to x will be available to the closures; That is exactly similar to how an instance variable behaves in a class.

We can also see how the usage of closure when it's a function or a class didn't change. We can actually replace the class with the function implementation and the calling point would need zero alteration.

Let see the implementations side by side:


Comparison of closure and class implementations


Wrap up

Alright, its time to wrap up. We started by reviewing how the variables in the lexical context are shareable and mutable between multiple closures. We then proceeded at creating an implementation of a counter both as a set of closures and as a class.

Finally, we converted the class implementation of the Counter to a function that returns a tuple of closures. And we saw how both the function and the class implementations are very similar to the point that we can replace the class with the function and the usage would be identical.

A gist for the counter function implementation is here, and as a class.

If you enjoyed it consider following me on twitter @ifnottrue to keep in touch :)