Currying, Spice Up Your Javascript Functions
Currying is an interesting technique that will power up your functions usage. In this article we’re going to explain it from basic example to some more advanced use cases and you’ll see that knowing this pattern, will give you some extra power as a developer.
It’s time to cook, let’s spice it up!
Definition
To begin, a definition won’t hurt.
Currying is a process which allows you to bind some arguments to a function so that, by the next invocation, these values are already fixed. It’s oftenly referred as ‘partial functions’. You can see it as a way to prefilled some of the arguments to obtain a more specific function.
But, enough talking it’s time for a basic code example!
Basic example
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Now it should be more clear for you. The liker
is a curried function. As you can see, we use it to prefill the first argument before the final function is executed.
This allows us to create more specific likers function as bookLiker or tedTalkLiker in our case.
It was the most basic example to introduce you with this concept, so it’s now time to move forward.
Advanced usage
We can write a curry helper function that is going to transform any “standard” function into a curried one. We’ll move from step to step on the implementation, so that you can absorb more easily the process.
So, let’s start with the first one.
1 – A naive implementation
1 2 3 4 5 6 7 8 |
|
Let’s have a look.
First, it stores the arguments passed to our function in a args
property. Except for the first argument (the function we want to curry).
It then returns a function. When you then call this function, the old arguments (stored in the args
property) are concatenated with the new arguments received and applied to the curried function fn
.
For those who didn’t know, arguments
is a specific word in Javascript and it corresponds to the arguments passed as parameters (even if they are not specified in the function signature). This arguments
variable behaves like an Array
but it’s not from an Array
type, that’s why you’re seeing those Array.prototype
calls.
To illustrated it, a use case can be a sendMessage
function:
1 2 3 4 5 6 7 8 9 10 11 |
|
Well that’s fine, but as you can see the implementation is quite naive and can’t resolve all the currying case, but we’re getting closer to the final syntax.
2 – A better implementation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
And the magic is on! This curry implementation is now way more robust.
1 2 3 4 5 6 7 8 9 |
|
Wohohoh! We’ve made it! And as you can see, it can be quite useful to have this syntax available. Furthermore, a major advantage is that the curried function is totally transparent as it still can behave as a normal one (look at the third line on this example, we can call it in a ‘normal’ way).
And we’re done! I hope you liked it.
No. You can go further!
Wait, what? Isn’t that enough? You’re not impressed yet?
Ok ok, it’s only because I like you, nice reader, (and because you’ve managed to read it so far), that we’re going to improve this function.
3 – The spiciest curry function
I hope you’re ready because this is going to be tastier than a ghost pepper (a pepper 900.5 times hotter than a Tabasco sauce according to wikipedia!).
For this last example I’m using the _
notation to refer to an ‘empty’ or a ‘placeholder’ variable.
1
|
|
Attention, this could enter in conflict if you’re using a library as lo-dash. So, to avoid this conflict you can easily replace the _
variable on the following examples with the keyword undefined
. Also, if you need one of your parameters to be equal to {}
, this code won’t work. So going with undefined
is a way more bullet-proof solution. But the _
notation is more simple to read.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
|
This is it! The implementation is really different from our initial naive implementation. Because here we have to handle the holes
and manage our args
differently.
Basically, the main difference here is the for
loop. We just keep references to our arguments holes
and we use them to build our args
correctly.
This is more complex but now the usages are really interesting.
Let’s have a look:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
I kept the examples simple so that you easily understand the concept. If you run the second one in your console, you’ll see that it’s logging everytime you move/click with your mouse.
Voilà, you reached the end of this article! To go further you can even try to refactor and then add the curry
function to the Function.prototype
itself.
I hope you’ve learn something new here and that you’re going to use it on your own projects. Feel free to write any comments.
If you want to discover more about Javascript, you can have a look to this serie of articles