Currying is probably better known within functional languages. In it’s simplest form we can view a currying as a way to declare a function and if a user of the function supplies less arguments than expected then a function is returned which takes the remaining arguments.
Let’s look at currying using a functional language such as F# first, as this really shows the usefulness of such a capability. We’ll define an add function which takes three parameters
let add a b c = a + b + c
Now we can write code such as
let r = add 1 2
Note: when we create a new function from our curried function, such as r in above, we can call this a partially applied function.
As you can see, we have not supplied all the arguments and hence r is not an integer but is instead a function which now accepts a single argument, i.e. the final argument the add function expects. Therefore we can write the following code against the returned function
let i = r 3
Now, i is an integer and contains the result of add 1 2 3 function call (i.e. the value 6).
Currying comes “built-in” syntactically in languages such as F#. We can write explicit code to demonstrate what in essence happens when we work within currying capable languages. Here’s an F# example which shows how we create functions returning functions along with closures to pass the preceding function arguments to each inner function
let add a = let add1 b = let add2 c = a + b + c add2 add1
Note: The F# compiler does NOT create the code equivalent to the above when we create functions unless the usage of the add method includes using it in a curried scenario.
The above is written in F# but you’ll notice that this same technique can easily be written in languages such as C#, Java etc. Here’s the same code in a verbose implementation in C#
public static Func<int, Func<int, int>> Add(int a) => new Func<int, Func<int, int>>(b => (c => a + b + c));
Thankfully C# allows a less verbose syntax, so the above can be rewritten as
public static Func<int, Func<int, int>> Add(int a) => b => (c => a + b + c);
To call such a function we’d need to write code such as
var i = Add(1)(2)(3)
This is not as elegant as the F# code (in my opinion) but does allow currying and partially applied functions in C#.
As you’d expect – another functional language, Scala, supports currying using the following syntax
def add(a : Int)(b : Int)(c : Int) = a + b + c; val r = add(1)(2)_ // or alternate syntax // val r = add(1)(2)(_) val i = r(3)
Notice that we require the _ (underscore) to ignore the third argument and we need to wrap each argument within brackets (creating parameter groups) to enable the function to be curried. The missing last argument need now be enclosed within brackets.
Scala also allows us to create partially applied functions where it’s not just the last n parameters that make up the new function. For example (let’s change the argument types to a string to the output is more obvious.
def mid(a : String)(b : String)(c : String) = a + b + c; def m = mid("Start ")(_:String)(" End") println(m("Hello World")) // outputs Start Hello World End
In this case we’re making a partially applied function using the curried function mid where in usage we miss out the middle parameter in the example usage. However we must also supply the type along with the _ placeholder.