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.

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):

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:

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.

If you take issue with this as a measure of language power, take it up with Mr Graham. Though I warn you, he’s probably quite good at arguing his case. ↩

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. ↩

Those who are familiar – please be gentle with me and my explanation! ↩

Note I said compact, not neater or cleaner or more expressive. But I happen to think it’s those things too. ↩

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. ↩

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. ↩

That’s right, almost everything. Not everything. Grrr. Though, otherwise, I really like this language feature. ↩

Interestingly, it will allow you define += return a value when you write it for your own classes. This is probably not a good idea. ↩

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. ↩

You can go a little further. As you said, if a closure or function contains only one expression, that is automatically the return value without needing an explicit `return` keyword. So you can do this:

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

Personally, I prefer not to use an `incf` function because that feels like we’re trying to simulate Ruby’s side-effect-ful `+=` operator without any good reason. But I do like the above three lines; very succinct.

Are you sure functions support the same single-expression means no return needed feature that closure expressions do? If I cut and paste that statement into a playground, I get a compiler error: Braced block of statements is an unused closure.

Of course, you can not bother with the func keyword at all, and do this, which amounts to the same thing: