Hi there! Today's post is a continuation of this post, so get ready to learn more about functional programming in Javascript! This post will cover the call and apply keywords and use these to build up to the topics of currying and partial application. Unfortunately I won't be showing you how to make actual curry (har har...), but this should still be a pretty neat introduction to the power of functional programming.

To begin with, one of the most fundamental topics to grasp is the role of functions in Javascript. I mentioned in the previous post that functions were what are known as first class and were an actual data type. A more concise way of explaining this: a function is an object! This explains why we can throw them around just like any other variable. All function objects are of the class Function, which, as you might have guessed, has its own set of prototype methods (accessible and extensible via Function.prototype) as well as member methods.

The first method we will be discussing which all functions possess is the call method. The call method allows you to invoke a function with a given context (accessible from inside the function body through the this keyword) and set of arguments. Here are a few examples of how you would use call:

 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
// The syntax for call is: func.call(context, arg1, arg2, ..., argn);

var alertFunction = function(){
    alert("Hello, I was called!");
};

// Simply call the method, which will show the alert box.
alertFunction.call();

// By passing a context as an argument of call, we can use this
// to interact with it.
var contextFunction = function(){
    alert("Hello, " + this.name + ". You are part of this!");
}

var contextObj = { name: "Super Cool Reader" };

// Remember that the first argument passed to call will be used
// as the context.
contextFunction.call(contextObj);

// Finally, we can also pass arguments to call.
var loggingFunction = function(message1, message2){
    // We store the logging function in the context.
    this(message1 + "\n" + message2);
}

// Remember that we can pass around functions as variables, yay!
loggingFunction.call(alert, "Hello, world.", "I am an argument!");


// Note that if we pass less arguments then a function needs,
// the other values are set to undefined.
loggingFunction.call(alert, "Hello, world. I am :");

As you can see, the call method can be quite powerful as we can now dynamically invoke a method with a given context. This is great for things like click handlers, when you want to use the clicked element as this throughout the handler. However there is one limitation to the call method: it expects x + 1 arguments if the function being invoked has x arguments. As you will see later on, this can be quite restrictive. This introduces us to the apply keyword! The apply keyword works in the same manner as the call method, however it only takes two parameters: the context and an array of arguments being passed to the function. This is great as we can now dynamically build lists of arguments to pass to a function without having to hard code the variable names, and is much more powerful. An interesting thing to note is that whenever you are inside a function body, an object exists called arguments which contains all the arguments for which that function was invoked with. I bolded the word object because although Javascript lets you iterate through it like an array and makes it look like an array, it is actually an object, and therefore does not have all array methods.

 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
// For example, we have a function which accepts an element, a CSS attribute
// and a new value. We are passing the element to update as the context!
var updateCss = function(attribute, value){
    this.style[attribute] = value;
}

var someDiv = document.getElementById('someDiv');

// As you can see, the arguments are passed as an array
updateCss.apply(someDiv, ['backgroundColor', 'red']);
updateCss.apply(someDiv, ['textAlign', 'center']);
updateCss.apply(someDiv, ['fontSize', '5em']);

// We can also combine the arguments array and apply function to make variadic 
// functions, in other words functions which accept a variable number of 
// arguments.
var sumFunction = function(){
    var sum = 0;
    for (var i = 0, l = arguments.length; i < l; i++)
        sum += arguments[i];
    return sum;
}

console.log(sumFunction.apply(null, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]));
console.log(sumFunction.apply(null, [10, 10, 10, 10]));
console.log(sumFunction.apply(null, []));

As you can see, the apply function is much more powerful and allows us to pass a variable number of arguments. If we wanted to implement the sum function using call, our function would have to accept an array and iterate through that, rather than the arguments object. One interesting side note: the pattern of iterating through an array and adding the result of a function to a total count (in our case our function is a basic addition) is an extremely common pattern in functional programming known as folding, reducing or accumulating. I encourage you to check it out here as well as to check out the built-in array function reduce and to try and implement it as an exercise.

This ability to invoke functions dynamically with an array of arguments makes for some interesting implications. Currying is a technique which comes from mathematics and essentially allows you to transform a function which accepts more than one arguments into a nested chain of functions each accepting one argument. This may sound confusing, so I will try to explain it in the context of Javascript: currying a function which accepts at least 1 argument allows you to create a new function which has a fixed value for the first argument and accepts values for the remaining arguments. One way to explain this is through this basic code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
var addThreeValues = function(a, b, c){
    return a + b + c;
}

// Suppose you have a 'curry' function which curries a function
// by accepting the function and the argument, this will create
// a function which accepts two arguments and returns the following
// values:
//      10 + b + c, where b and c are the two arguments.
var addTwoValues = curry(addThreeValues, 10); 

// If we curry the addTwoValues function with the value 25, 
// it now returns a function which accept 1 argument and returns
// the following values:
//     10 + 25 + c, where c is the one argument.
var addOneValue = curry(addTwoValues, 25);

// Finally, if we curry the addOneValue function with the value
// 3, it retursn a function which accepts no arguments and 
// returns the following value:
//     10 + 25 + 3
var getCalculatedValue = curry(addOneValue, 3);

As you can see, currying allows us to continuously create a 'copy' of our original function with the value of the first argument being declared. What's kind of cool about this is that we can represent any function as a series of curried functions, a result which is emphasized in Haskell. But now you are probably wondering how the curry function is actually implemented! There are two approaches to this: one is to create a curry function which accepts a function to curry like shown above, and the second is add a curry function to the Function prototype so that we do not have to pass a function. For the sake of simplicity, we will be taking the first approach, however if you have any questions about implementing it the second way feel free to post on the comments! You will also notice that we convert the arguments object into an actual array by using the Array prototype's slice function, a trick I picked up here.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
var curry = function(func, firstVal){
    var fixedArg = [firstVal];

    // We return a function which simply applies the original function
    // with the firstValue prepended to the arguments array. Remember
    // that the arguments array is dynamic, so we do not need to put
    // the arguments in the function signature.
    return function(){
        return func.apply(this, fixedArg.concat(Array.prototype.slice.call(arguments)));
    }
}

And there you go! Go ahead, test it out and play around with it! Create more than one curried version of the same base function but different fixed variables to see what you get. Now you may have noticed a limitation with currying: by definition, currying fixes only the first variable. This is where partial application comes in! Partial application is essentially like currying, however rather then being able to fix only the first parameter, we can now fix as many parameters as we want (in continuous order of course). We can actually easily modify our curry function to handle this, and again it can also be done via the Function prototype.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
var partial = function(func){
    // Get all the arguments passed to the function apart the first one (the function)
    var fixedArgs = Array.prototype.slice.call(arguments).splice(1);

    // We return a function which simply applies the original function
    // with the firstArgs prepended to the arguments array.
    return function(){
        return func.apply(this, fixedArgs.concat(Array.prototype.slice.call(arguments)));
    }
}

As you can see, the only line the actually changed was line 3, in order to support passing more than one argument to the partial method. In fact, you could even implement the partial function using the curry function. We can now use it like so:

 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
// A basic cross-browser event binding function
var bind = function(element, event, callback){
    if (element.attachEvent) {
        element.attachEvent('on' + event, callback);
    } else {
        element.addEventListener(event, callback, true);
    }
}

// We can now use partial to create binding functions
// for specific elements and events.
var someDiv = document.getElementById('someDiv');
var someImg = document.getElementById('someImg');

var divClickBinder = partial(bind, someDiv, 'click');
var imgEventBinder = partial(bind, someImg);

// We can now use our partial binder functions with the
// remaining arguments.
divClickBinder(function(){
    alert("The div was clicked!");
});

imgEventBinder('click', function(){
    alert("The image was clicked!");
});

I think that we will end it here for today. Hopefully I've helped you understand a bit more about using Javascript for functional programming. Again, there is much more popular topics related to functional programming, but by combining this post with the previous post, you should now be able to apply most of the common patterns.

Thanks for reading, Dominic.