May 06, 2013
Functional programming has always been a bit of a mindbender for me. I’ve read plenty of tutorials on the subject, but it wasn’t until recently that it finally started to click for me.
The basics of partial function application involves something like this.
var slice = Array.prototype.slice; // just to simplify things
var partial = function(fn) {
var args = slice.call(arguments, 1);
return function() {
return fn.apply(this, args.concat(slice.call(arguments)));
};
};
Bwah?
What this does is take a function as a parameter. It then takes all the other parameters and hangs on to them. It returns another function, that when called, executes that first one, with the original arguments and any new ones you pass in.
Bwah?
Let’s use a primitive example to try to unwind this thing.
var add = function(a, b) {
return a + b;
};
var add5to = partial(add, 5);
Now when you call add5to(3)
you’ll get 8. Yes, this will always add 5 to whatever you supply to it. Yes, it is absolutely useless.
This is where a lot of tutorials stop, leaving you to think “OMG WHO CARES?!” and then get back to doing important things, like stamp collecting.
And that’s where I stopped for the longest time too. But then when I watched this video a light came on to realize that this could be useful. You can use it to build a pretty nice DSL that creates nested DOM elements.
Let’s say you have a function called el
that takes tagName
, attributes
, and content
as parameters.
var el = function(tagName, attributes, content) {
// snip
};
var element = el(“div”, {className: ‘foo’, id: ‘bar’}, “Hi I’m a div!”);
// results in:
// <div id=“bar” class=“foo”>Hi I’m a div!</div>
Let’s also say that if you leave out attributes
, it treats the second parameter as content
.
el(“p”, “Call me Ishmael.”);
// <p>Call me Ishamel.</p>
That in itself is a little useful, but here’s where partial function application comes in. Cram el
into partial
and stuff starts to get real.
var div = partial(el, “div”);
var element = div({className: ‘foo’, id: ‘bar’}, “Hi I’m a div!”)
In fact, we can quickly make functions for many HTML tags.
var DOM = {};
[“div”, “p”, “ul”, “ol”, “li”].forEach(function(t) {
DOM[t] = partial(el, t);
});
Now you can string a bunch of stuff together.
var list = DOM.ul(
[DOM.li(“one”),
DOM.li(“two”),
DOM.li(“three”)]);
Theeeeen, take into account something like map
and you can really start to make some magic.
var people = [{name: “Scott”}, {name: “Bob”}, {name: “Barry”}];
var names = people.map(function(p) {return DOM.li(p.name); });
var list = DOM.ul(names);
All of a sudden you have a quick list of DOM elements with names of people in them. You can refactor that out some more, but I wanted to just focus on just the partial
bit of this.
When would be a good time to use this? When you have a bunch of functions that act similarly but vary slightly on parameters.
The power of this lies in that you can take an incredibly simple function, and then use it to build complex mechanisms out of it. I’m still nowhere near an expert on this, but I think this time the wrinkles in my brain may just sink in.
Written by Scott Williams who lives and works in sunny Phoenix, AZ. Twitter is also a place.