Function currying is something I wanted to dig into for some time now, and finally I found a good time for it, especially now, after some changes introduced to the syntax in Swift 3.

### What is function currying?

What is function currying (in general and in Swift)?

If you want to get a full definition, see Wikipedia. In short, function currying lets us write code that translates a function taking two arguments, into a function taking one argument, and returning a function taking the next argument (and so on for 2, 3, 4, … arguments).

It might not sound super clear yet, so let’s take a look at some examples.

func multiplyTwoNumbers(_ a: Int, _ b: Int) -> Int {
return a * b
}

multiplyTwoNumbers(2, 3) //result: 6

Super simple, takes two Integers and returns result of their multiplication. What we have here is a 2 argument function that we will transform (as in definition), into function taking only one argument, returning another function, taking the second argument and returning an Integer.

In pseudo-code it would be something like:

function(a, b) -> c
//into
function(a) -> (function(b) -> c)

You could ask - how is that useful? Well, it allows for this newly created (curried) function to be evaluated over a period of time, with each call passing only a subset of the arguments (and saving each call result on the way if needed).

So looking at our previous example, we could translate it into curried version like this:

func multiply(_ a: Int) -> (Int) -> Int {
return { b in a * b }
}

multiply(2)(3) //result: 6

At this point, there’s still no real advantage, and we have this funky syntax, which is not obvious when you see it for the first time. But like I mentioned earlier, it allows us to evaluate it over time, and save each call result on the way.

let multiplyBy10 = multiply(10)
//result: function that will multiply its argument by 10

let multiplyBy5 = multiply(5)
//result: function that will multiply its argument by 5

let multiplyBy2 = multiply(2)
//result: function that will multiply its argument by 2

Now you can call it like any other function:

let x = multiplyBy10(2) //result: 20
let y = multiplyBy5(2) //result: 10
let z = multiplyBy2(2) //result: 4

If we wanted to achieve same thing without currying, we would have to write a new function, for every first argument combination, like this:

func multiplyBy10(_ a: Int) -> Int {
return a * 10
}

func multiplyBy5(_ a: Int) -> Int {
return a * 5
}

func multiplyBy2(_ a: Int) -> Int {
return a * 2
}

Much more writing, error-prone (most probably would implement it by copy-pasting) and when you know what function currying is, there’s no real difference in readablity (in my opinion).

### Transforming standard functions into their curried versions

So far, we’ve been able to transform our own two-argument function into curried one. That’s quite easy, as we just rewrote it from scratch. Lets try to do something more complicated - tranform in a similar way UIColor.init(red: green: blue: alpha:) function, which we cannot modify directly in the source code.

How can we create curried function out of one that’s not curried? We need to implement a function that takes an existing function as a parameter (the one we want to transform) and returns a curried wrapper around it.

Before we go with UIColor’s init function, we will start by transforming our own multiplying function. To do this, we will create a function that takes (Int,Int)->Int function as an argument and returns a curried wrapper around it.

func curriedVersion(f: @escaping (Int, Int) -> Int) -> (Int) -> (Int) -> Int {
return { a in { b in f(a,b) } }
}

(What is @escaping keyword? For more info I encourage you to visit Apple docs, but in short – we use it to mark a closure that will not be invoked directly by function taking this closure as an argument. In our case, we don’t call f function directly, we just pass it around and return it to be called later)

As we see, our curriedVersion function, takes as an argument a function (that matches multiplyTwoNumbers signature) and returns a function, that returns a function, that returns an Integer (I know it might be hard to follow, but bare with me).

Originally, our curried function multiply returned a function, that took one argument and returned an Integer. Because we’re transforming a function here, we need a wrapper around it. Let’s take a look again at pseudo-code:

Standard function taking two arguments and returning a number

standardFunction = function(a,b) -> c

Curried function that takes one argument and returns a function taking second argument, and returning a number

curriedFunction = function(a) -> (function(b) -> c)

How do we make curriedFunction out of standardFunction? We create a wrapper around it

transformingFunction = function(standardFunction) -> curriedFunction

If we now substitute function names with their definitions we get

transformingFunction = function(function(a,b) -> c) -> function(a) -> (function(b) -> c)

which looks similar to

func curriedVersion(f: @escaping (Int, Int) -> Int) -> (Int) -> (Int) -> Int

Ok, so how do we use our transforming function? We just call it by passing to it our old multiplyTwoNumbers function.

let curriedMultiply = curriedVersion(f: multiplyTwoNumbers)
curriedMultiply(2)(3)

### Transforming UIColor.init() into curried function

Ok, now that we successfully transformed a 2 arguments function into its curried version, let’s go back to our goal - transforming UIColor.init(red: green: blue: alpha:) function that takes 4 arguments (as I mentioned earlier – same can be applied to any 2+ argument function).

func transformColorInit(f: @escaping (CGFloat, CGFloat, CGFloat, CGFloat) -> UIColor) -> ((CGFloat) -> (CGFloat) -> (CGFloat) -> (CGFloat) -> UIColor) {
return { red in { green in { blue in { alfa in f(red, green, blue, alfa) } } } }
}

Might look hard to read, but it’s quite simple - our transformColorInit takes as an argument function that matches the signature of UIColor.init(red: green: blue: alpha:) and it returns a function that takes a float and returns a function, that takes a float and returns a function, that takes a float and returns a function, that takes a float and returns a color.

General rule is – you strip away one argument at a time.
If your initial function takes 2 arguments - you will have function returning a function 2 times.
If it takes 4 arguments (like UIColor.init(...)), you will have function returning a function 4 times etc.
Other than the syntax of it looking a bit weird, I think it should be quite easy to understand.

How do we use our transformer now? As before, we just call it, by passing to it UIColor.init(...) function.

let curriedInit = transformColorInit(f: UIColor.init(red: green: blue: alpha:))

(notice that we need to pass full signature of init function – it’s because UIColor has more than 1 init function taking 4 CGFloat arguments)

Now we can e.g. create a function, that will be creating red color with different values of alpha channel (passed as an argument).

let createRedWithAlfa = curriedInit(1)(0)(0)

let red05 = createRedWithAlfa(0.5)
let red02 = createRedWithAlfa(0.2)
let red09 = createRedWithAlfa(0.9)

Of course, you’re not limited to just last argument, you could also make a function taking 2 or 3 arguments if you needed to:

let createBlueColorWithAlpha = curriedInit(0)(0)

let semiTransparentBlue = createBlueColorWithAlpha(1)(0.5)
let solidBlue = createBlueColorWithAlpha(1)(1)

### Generic tranforming function

Do we need to write a different transforming function for every function that we want to transform? Fortunately, the answer is NO.

We can use the power of Swift’s generics and write a generic function, that will take as an argument function with non-specified argument types (can be Int, Float, String, Class type etc) and return its curried version.

For 4 argument function (like UIColor.init(...)) it could look like this:

public func curry<A, B, C, D, E>(_ function: @escaping (A, B, C, D) -> E) -> (A) -> (B) -> (C) -> (D) -> E {
return { (a: A) -> (B) -> (C) -> (D) -> E in { (b: B) -> (C) -> (D) -> E in { (c: C) -> (D) -> E in { (d: D) -> E in function(a, b, c, d) } } } }
}

It is a generic function with 5 different placeholder types – 4 of them for arguments of passed function and 1 for its return type. Of course, nothing stops us from passing a function that has all 4 arguments of the same type.

let createRedWithAlfaV2 = curry(UIColor.init(red: green: blue: alpha:))(1)(0)(0)

let red01 = createRedWithAlfaV2(0.1)

Code for curry function was written by guys from thoughbot – feel free to take a look and see an example for function transforming a function taking 20 arguments :)

That’s it for today. You should know what function currying is, how to use it and how to transform any 2+ argument function into its curried version. If you have any questions – let me know in comments!

Sources (I recommend you to read first 3 positions, they did help me to understand better what function currying is!):