You might have heard of currying: it’s a strange name for a really, really useful technique (it comes from this dude). Here I’m going to cover what it is, why you need it, and then take a look at a useful function for currying built right into Javascript (ES5+): bind
.
Currying
I like curry. But I think I like currying even more. So what is it?
Currying, also known as ‘partial function application’, is complicated to explain in just words, but I’ll give it a go:
Partial function application is fixing a set of arguments to a function, producing another function to be used later.
The new function that’s produced is like a cloned version of your first function, except that some arguments are set and can’t be changed. You set the arguments when you ‘curry’ the function.
Here’s an example in psuedo-javascript:
Here we’re currying the add
function to produce a new function, add_ten
, that is actually our add
function but with the first argument fixed at 10. When you call add_ten
you supply the second argument to add
.
Neat, huh?
Yup, but how does it work?
Well, let’s create an implementation of curry
from scratch.
If you haven’t already, it’s worth reading my call & apply post becuase this example will make heavy use of them both.
What we’re going to do it make a really dumb version, then tweak and optimise as we go. We’ll start simply by making the example above work.
Here it is in proper-javascript, with added (bad) curry sauce:
fifteen
is 15. Nice. But that bad_curry
function is pretty useless for anything other than a 2 argument function. Let’s see what we can do.
Infinite arguments
So here’s a new curry function that supports any number of arguments.
Chyeah. Here’s the explanation:
In case you didn’t know, [].slice.call(arguments)
turns arguments
into an array (cos it’s not one).
meh_curry
uses that a couple of times: first, it stores the fixed arguments, and extracts the function we are currying from the front of the array (by shift
‘n it).
It then returns a new function that concatenates the fixed arguments to any arguments it recieves, and then runs the initial function using apply
, passing an array of all the arguments concat
‘d together. Nice!
But, I think we can do a little bit better.
Ninjafy
I’ve cut the above meh_curry
into a flavoursome alternative, curry
:
I’ll leave it to you to see what I’ve done – if you have any questions then just ask in the comments.
By the way: ‘currying’ and partial function application are technically not the same thing, but the difference is relatively insignificant.
Bind
bind
is really cool, let’s check it out…
Javascript’s real name is ECMAScript, but since that’s almost a skin condition, we mostly stick with Javascript. Most of the JS you write conforms to the ECMAScript3 specification (ES3). However, ES5, the new specification (available in most browsers these days and polyfillable where not found), adds some rather useful things to the language. One of these is bind
.
bind
is your friendly neighbourhood currier. You can call bind
on any function (where ES5 is available) to specify what the value of this
should be when the function is called. It doesn’t actually call the function (unlike call
and apply
): it returns a new function where this
is bound to whatever you pass into bind
.
Why might you want to do that? Well, consider this:
In that (contrived) example, person
has a greet
method that references this.name
. If we just called person.greeter
we’d get “Example Person says: Hello!” back. That’s ok, but we can use bind
to have Tom
do the greeting:
Binding & currying
Bind does more than that too. It can actually be used for the same kind of function currying that we were doing above, because it will also pass any further arguments you give it (after the value of this
) to the function you are currying. Like this:
DIY curry binder!
So bind’s cool. But the best way to learn how something works is to build it, so let’s make our own version of bind
based on curry
from earlier.
We’ll take the function to be curried as our first argument, the value of this
as our second, and then fix all the rest of the arguments.
Woopee! We can use it like this:
Real examples
So where would you use these in real life?
setTimeout
This pattern is pretty common:
But dayum, it’s ugly. How about this?
Ah, much nicer.
pubsub
If you’re using a pubsub system, you may want your event-handling callbacks to be to bound to the correct this
. Some pubsub systems support doing so, but here’s how make sure of it, using bind.
And we’re done
Currying is really useful tool to have in your arsenal, allowing you to write much cleaner, more expressive code. And since bind can be found in all modern browsers (and can be added to older browsers), so why not try it out?
Once again, thanks for reading, and don’t forget to share this article if you found it useful!