An Accumulator in Swift, Part 2 – Using Generics

In Part 1 of this post, we wrote an implementation of Paul Graham’s accumulator problem in Swift. Here’s one of the versions:

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

This looks pretty similar to the Ruby version he gives:

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

Except there’s a problem. On his page of guidelines for submitting an example in a new language1 he points out it needs to:

[work] for any numeric type – i.e. can take both ints and floats and returns functions that can take both ints and floats. (It is not enough simply to convert all input to floats. An accumulator that has only seen integers must return integers.)2

In Ruby, this isn’t an issue because of the duck typing. But in Swift, if you try to pass a Float to foo, you’ll get an error. We’re going to have to use another feature to fix this – generics.3

First let’s try implementing incf using generics, so it can take an Int or a Float. We do this by defining a type parameter T in angle brackets after the function name, and then using that instead of the explicit Ints:

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

Oops, more compiler errors. “Could not find an overload for ‘+=’ that accepts the supplied arguments” again.

This is because not all objects have a += operator, so if you tried to use it with one of those, it wouldn’t work. Unlike in C++ templates, where you wouldn’t get a compiler error4 unless you tried to use incf with a type that was missing a +=, Swift requires you to restrict your types up-front.

The way you ensure a type will support the necessary member functions is by using Type Constraints. These are protocols you append to your generic type. For example, if you wanted to write a generic less_than function, you could use the Comparable type:

func less_than<T: Comparable>(lhs: T, rhs: T) -> Bool {
    return lhs < rhs
}

Only classes that implement the Comparable protocol can be used with the less_than function, and because they impelement this protocol they’re guaranteed to have a < operator.

The Swift standard library only defines 3 protols so far – Equatable, Comparable and Printable.5 They don't cover what we need, so we'll define our own. Let's call it, uhmm, Addable.

protocol Addable {
    @assignment func += (inout left: Self, right: Self)
}

Then, we need to declare that Int and Float support Addable by extending them with the new protocol:

  extension Int: Addable { }
  extension Float: Addable { }

Finally, let's try our generic function with the new constraint:

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

Now, if you pass in a Float to foo, it works.6. In fact, if you tag any type that implements += it will work for that type too. Try it with String.

Anyway, with this requirement covered, hopefully we can add Swift to the pantheon of powerful languages. Maybe one day they'll take new submissions to the page!


  1. These pages tell a story. First he was all hey guys, let’s get all the examples, this is cool! Then he’s like, no you numbskulls, read the problem, that’s not what it says! Eventually he gives up and tells people to stop emailing him. 
  2. Strictly speaking what we’ll implement still doesn’t cover this requirement, because the quote and the example following it implies it needs to be able to switch dynamically between integers and floating point halfway through. Read the next part for a solution to this. 
  3. I love generics. But then the first language they taught me in college was Ada, and after that I spent years in the C++ mines, so it’s not surprising. 
  4. The compiler error will be about 10 lines long and will fill you with hopeless despair. Concepts, something similar to Swift’s protocol constraints, didn’t make it into C++11. 
  5. They don't define Assignable. I guess that's considered so fundamental you can take it as a given. Presumably they're going to add a lot more standard protocols to the library over time, so keep an eye on that page. There are several more implemented but not yet documented – to see them, type import Swift into playground, and command-click it. 
  6. I was pretty amazed when it did the first time I tried this. 

An Accumulator in Swift

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.


  1. If you take issue with this as a measure of language power, take it up with Mr Graham.#160;
  2. If you’re eyeing foo suspiciously, and wondering why it isn’t called, say, makeAccumulator, I agree with you. 
  3. I’m not wild about the Swift syntax for type definitions of functions returned from functions. I know it’s completely unambiguous if you read it from left to right but it makes me nervous when I look at it. I don’t have any better proposals, either. 
  4. Those who are familiar – please be gentle with me and my explanation! 
  5. Note I said compact, not neater or cleaner or more expressive. But I happen to think it’s those things too. 
  6. Terms like strong or duck typing are not rigorously defined, but people can get very emotional about it when they think they’re being used incorrectly. Please email Casey. 
  7. I do wonder why they decided to not have assignment return the value of the left-hand side. Seems like this is a legit use case. I guess maybe they they thought it was too side-effecty to change a value while also using it? But if you’re going to do that, go all the way and ban ++i from being used on the right-hand side of expressions – but that would probably lead to the C guys assaulting the castle with torches and pitchforks. 
  8. That’s right, almost everything. Not everything. Grrr. Though, otherwise, I really like this language feature. 
  9. Interestingly, it will allow you define += return a value when you write it for your own classes. This is probably not a good idea. 
  10. Yes I’m aware writing a two-line function just to compact less code elsewhere is a bit silly, but give me a break, we’re just experimenting here. Plus I think the lisp “build up the language to meet your problem” thing is a nice idea.