In an appendix to his article Revenge of the Nerds, Paul Graham suggests a problem to solve in a programming language to see how “powerful” that language is.1

The problem: Write a function foo that takes a number n and returns a function that takes a number i, and returns n incremented by i.

Also note,

(That’s incremented by, not plus. An accumulator has to accumulate.)

Solving this problem is one of the first things I try when learning a new language. This article will implement various versions this function in Swift, as a way to explore some of Swift’s features.

Here’s a first attempt. It’s very similar to the makeIncremetor function in the Closure section of the Apple Swift book, except adapted to match Graham’s definition of the problem:2

func foo(n: Int) -> (Int) -> Int { var acc = n func inc(i: Int) -> Int { acc += i return acc } return inc }

Read that first line defining foo as: it takes a parameter, n , and returns a function, which itself takes an Int as a parameter and returns an Int .3

That returned function is a closure – a self-contained combination of a function and an environment of variables (in this case, just one, acc ). Each time you then call that returned function, it adds the value i you pass in to acc to keep a running total, and then returns the latest total.

In case you’re not familiar with closures, here’s a short explanation of what’s happening.4 When declared, the function inc “captures” the outer variable acc , so instead of acc being destroyed when it falls out of scope, it sticks around and continues to be useable by the inc function. Note that if you call foo again, it creates a brand new inc function/ acc variable pairing, starting from whatever n you just passed in. Think of this as similar to creating a new instance of a class with a member variable acc, initialized with n .

So, people have been enjoying comparing swift to other languages. I like Ruby, so let’s take the Ruby example from Graham’s list of canonical solutions to his problem.

def foo (n) lambda {|i| n += i } end

Well that’s a lot more compact!5 Let’s look at why, and get our Swift example closer.

The Ruby example just captures and uses the input parameter n for its state variable. We can do this in Swift too, with the addition of the var keyword in front to allow it to vary (without those changes affecting the caller’s passed-in variable):

func foo(var n: Int) -> (Int) -> Int { func inc(i: Int) -> Int { n += i return n } return inc }

Next, the inner function is anonymous, and returned directly. We can do that in Swift too. Unlike in Ruby, we don’t need to use a lambda keyword to declare an anonymous function:

func foo(var n: Int) -> (Int) -> Int { return { (i: Int) -> Int in n += i return n } }

Now let’s look at all those type declarations cluttering up the place. Ruby doesn’t have them because it is duck typed. Swift on the other hand is strongly typed.6 But there is hope – some of them can be eliminated by Swift’s type inference. In the inner function, we already know the types of everything being passed in or returned, so we can leave them off and the compiler infers them from the context:

func foo(var n: Int) -> (Int) -> Int { return { i in n += i; return n } }

Do we still need the declaration of i ? If the types can be deduced, you can use $0 , $1 etc for the arguments, and skip the in .

func foo(var n: Int) -> (Int) -> Int { return { n += $0; return n } }

Finally, so long as a closure is just a single expression, you don’t need an explicit return – the result of the expression is automatically returned. This leaves us with something very similar to Ruby, where the last statement is always returned (in Ruby’s case, even with multi-line functions).

func foo(var n: Int) -> (Int) -> Int { return { n += $0 } }

Except oops, no, that last one won’t compile. “Could not find an overload for ‘+=’ that accepts the supplied arguments” it says. That’s a little confusing, because the “argument” in question is actually the return type. In Swift, += doesn’t return a value7 (unlike in Ruby where almost every statement has a value8 and can be used on the right-hand side, even an if statement).

If you were thinking, I know, let’s override += to return a value, nope Swift won’t let you do that.9 Also, you’re the reason I hate other people’s code. To get inspiration for an alternative function, let’s look at the lisp example from the canonical list:

(defun foo (n) (lambda (i) (incf n i)))

And here is an implementation of that function:

func incf(inout lhs: Int, rhs: Int) -> Int { lhs += rhs return lhs }

Note the use of the inout keyword to indicate that the changes made to this parameter affect the variable passed in by the caller, unlike with var .

Since our new function returns a result, we can now use it to implement a single-expression closure:10

func foo(var n: Int) -> (Int) -> Int { return { incf(&n, $0) } }

Swift requires you to put an & in front variable when passing in an inout parameter, which is nice as it means you can’t accidentally miss the possibility of side-effects.

That’s probably as far as we can go. It’s pretty similar to the Ruby version at this point. Except… we didn’t quite solve the stated problem. To find out why, read on to Part 2 of this article.