ES6 Currying
In programming there is a paradigm called functional programming. The topic is broad, sometimes elusive and encompasses many different sub topics. In this article we try to demystify one of the concepts of functional programming called currying. It has nothing to do with food, but is instead named after Haskell-Curry, the American mathematician.
A curried function takes multiple arguments one at a time.
If you have been using javascript for some time, chances are you have been using functions to write your code. These functions can take one, multiple or no arguments. The amount of arguments a function takes is called arity. A function that takes two arguments is called a binary function. This can look a little something like this
We have a function add which takes two arguments x and y and returns their sum. In order for this to work we have to provide both its arguments at the same time.
Now lets say you want to implement a function that increments whatever value you pass it by one.
Inc takes a number and returns the function add, where it has fixed its first parameter to always be one. Inside inc we still have to provide both arguments to add at the same time. Here’s where we could use currying.
The curried version of add takes an argument x, returns a function that takes an argument y and then returns the sum of x and y. Now this syntax might look confusing so lets see that written out a bit a bit more verbose.
Supplying parameter x the return value is a new function fixing the value of x inside its closure loop.
Closures
Quick refresher on closures. A closure is the combination of a function together with references to its surrounding state. That means you get access to a functions outer scope from an inner function. If we take another look at the example above, once the parameter x is passed in, a function is returned which takes another parameter. However due to closures this inner function still has a reference to the value of x.
Partial application
When add in our example is given a value x, we can say that the return function has been partially applied. It has some of its parameters fixed inside its closure loop.
Why curry
As we have now seen, currying is useful when you want to supply arguments to a function one at a time. It allows for more terse code, in which functions are more easily passed around. And it allows you to write in a point free style. Lets look at one more example
Here we have an array of characters. We want to find all characters of a specific race. To do that we use the filter method and supply it a function that, given arguments, returns a boolean based on a specified condition. This is called a predicate. Our predicate is findRace. It is currently uncurried and as such we need to provide both arguments to it at the same time (race, member). To use it inside the filter function, we need to first pass the current iteration to a function that applies it to an instance of findRace where the race parameter has been fixed to be ‘Hobbit’. With me so far? Good. Now this is quite verbose. Let’s see that again, but now with currying.
Here findRace is in its curried form. It first takes a race, it then returns a function that takes a member and once all the parameters are in returns a boolean value. Look at how cleanly we can now use it inside filter. We no longer need to wrap it inside another function. We no longer have to pass around parameters and in the end this makes our code easier to read.
Conclusion
Curried functions are not better or worse than regular functions, but they are a tool in your toolbelt when you find yourself passing around functions as arguments a lot and have a need to provide your functions with its arguments one at a time. It allows for terser and more easy to read code.
ordermanager bij Van Liere Media bv Emmen
4 年Klinkt interessant!