Hey, I'm writing a book too :) Click the link below to preorder and save ;)
»» Get the Only Reference You'll "ever" Need on JavaScript Engineering Interviews, Now! ««
November 5th in Functional Programming by .

Everything You Need To Know About JavaScript Functions (and more)

One Lambda to Rule Them All

One Lambda to Rule Them All

Functions are the building blocks of any JavaScript module. In this tutorial, we’ll have a glance on basic principles behind functional programming in JavaScript, along with some lesser known features of JavaScript functions.

This is mainly a follow-up, and a more in-depth analysis, of a former JavaScript Function Kung-Fu post.

Functions are First-Level Citizens

Functions not only form the basis of JavaScript‘s prototypal inheritance model, they are also the groundwork for many patterns such as the module pattern.

Almost all JavaScript libraries/frameworks utilize anonymous functions to be used as delegates and user-defined events.

Functional Programming

Functional programming is a programming paradigm that treats computations as the evaluation of mathematical functions and avoids state and mutable data.

Ref: http://en.wikipedia.org/wiki/Functional_programming

A “paradigm” is a conceptual model. A “programming paradigm” is a conceptual model for creating programs.

Modern languages are flexible enough to enable the usage of several paradigms. For example, C# has both object-oriented and functional features.

Object Oriented Programming and Functional Programming are also two different programming paradigms. Imperative Programming, and Declarative Programming are also examples of programming paradigms.

Especially if you are from an object-oriented background, you tend to visualize functions as actions that change the state of objects:

Customer.updateWorkAddress('Palo Alto, CA');

The updateWorkAddress method of Customer, changes the state of the Customer object.

A mathematical function does not have any state data. Contrary to object-oriented programming, functional programming avoids state data and mutable data.

Functional programming requires a totally different state of mind. However once you get used to it, you’ll love the flexibility of it. With a functional language like JavaScript, it’s extremely fun to think in terms of this concept:

In JavaScript we can pass a function as a parameter to another function. So instead of applying a set of functions sequentially to the data, we can modify the functions themselves to create a single overarching function to generate an expected outcome out of that data.

  • Higher Order Functions,
  • Pure Functions,
  • Partial Functions (i.e. Currying),
  • Template Functions,
  • Memoization,
  • And Recursion

are the basic concepts that revolve around the functional programming paradigm.

Fear not, for we will observe each of these concepts, and how they relate to JavaScript, one by one :) .

Higher Order Functions

Higher order functions are functions that either take a function as an argument or return it as a result.

The most obvious use of higher order functions is the usage of “callbacks”. Take o2.EventHandler, or o2.Ajax, for example. The functions that are passed to these objects are higher order functions.

Here’s an example:

o2.Ajax.get('http://o2js.com/', {test : true}, {
    oncomplete : function(responseText, responseXml, transport) {
        doStuff(responseText);
    }
});

Here’s another example.

function getNumber() {
    return 42;
}

function square(delegate) {
    return Math.pow(delegate(), 2);
}

// This will return 1764.
square(getNumber);

The square function above is a higher order function, because it takes another function (delegate) as an input parameter.

Pure Functions

A function is said to be “pure” when it has no side effects.

A pure function does not alter the external state or mutate any external data.

Let’s use a very simple example to illustrate the concept:

var state = {
    message : null;
};

function trimMessage(newMessage) {
    newMessage = o2.StringHelper.trim(newMessage);
    state.message = newMessage;
}

The above trimMessage function is not pure, because it alters the external state object.

Besides, the function smells because it it does two things at once (i.e. trimming the message, and updating the state data), and its name is misleading because it does not reflect the function’s total behavior.

Any function should only do one thing, and should do that thing well.

Let’s refactor the above code to “purify” the trimMessage function:

var state = {
    message : null;
};

function trimMessage(message) {
    return o2.StringHelper.trim(message);
}

function updateStateMessage(message) {
    state.message = message;
}

function processIncomingMessage(message) {
    var trimmedMessage = trimMessage(message);
    updateStateMessage(trimmedMessage);
}

Now, trimMessage is a pure function. It is doing what it’s intended to do, without altering any external data. Therefore, you can call it as much as you like, and in anywhere you like in your program.

The more pure functions you have, the more meaningful your program is. Your program will be more atomic, less prone to bugs, easier to read, easier to follow, easier to maintain, and easier to refactor.

Pure functions are closely tied to the concept of referential transparency, which says that an expression is considered to be referentially transparent when it can be replaced with its value.

Let’s take the above trimMessage function:

var trimmed = trimMessage('  hello world   ');

can be replaced with:

var trimmed = 'hello world';

without changing the program’s intention.

Closures

At this point, it would be useful to overview how closures work, before progressing further. We are about to enter the mystical world of functional programming, and to find our way around in this world a solid knowledge of closures will be our light.

The body of any function defines an execution scope. This function can refer to variables outside the body. The captured variables are set to be enclosed inside the function’s execution scope; hence the name “closure” comes.

Since every function (including global functions) has an outer context accessible to them, each function is, by definition, is also a closure.

The most surprising property of closures is the fact that they close over the scope, not the values.

Here’s an example to clarify all these:

var test = 'hello  world';

function printTest() {
    log(test);
}

test = 'hello stars';

// This will log: 'hello stars'.
printTest();

Template Functions

Functions that can generate other functions depending on a set of parameters are called (you guess) “generators“, or template functions.

Template functions are a way of eliminating code duplication.

Let’s rewrite the above square function as a template function:

function generatePowerRaiser(delegate, number) {
    return function() {
        return Math.pow(delegate(), number);
    };
}

function getTheMeaningOfLife() {
    return 42;
}

var square = generatePowerRaiser(getTheMeaningOfLife, 2);
var cube = generatePowerRaiser(getTheMeaningOfLife, 3);

// Returns "1764".
square();

// Returns "74088".
cube();

Function Name and Function Length

JavaScript provides a set of tools to help writing generators and other higher order functions with ease.

Two of these tools are the name and length properties of the function:

name will return the name of the function, whereas length will return the number of parameters it has.

Let’s follow with an example:

fuction calculateLine(a, b, x) {
    return a*x + b;
}

// Returns "calculateLine".
log(calculateLine.name);

// Returns "3".
log(calculateLine.length);

Flexibility Preferred Over Safety

Although we can get the number of parameters that a function expects, JavaScript is flexible enough to enable you call any function with any number of arguments.

This sacrifice of safety in favor of flexibility may disappoint the feelings of some, though it makes a library designers’ life a lot easier when you know and understand it:

function echoLineParameters(a, b, x) {
    log(a);
    log(b);
    log(x);
}

echoLineParameters(1, 2, 3);
// outputs:
// 1
// 2
// 3

echoLineParameters(1, 2);
// outputs:
// 1
// 2
// undefined

The arguments Object

Unspecified arguments will be considered undefined, and extra arguments will be simply discarded, unless you access them via the arguments object:

function testArguments(a, b) {
    log(a);
    log(b);

    for (var i = 0, len = arguments.length; i < len; i++) {
        log(arguments[i]);
    }
}

testArguments(1, 2, 3, 4);
// outputs:
// 1
// 2
// 1
// 2
// 3
// 4

Walks like an Array, Talks like an Array, but…

Arguments object is array-like, it has a length property and you can even enumerate through it. But it’s not strictly an array.

Don’t believe me? See for yourself:

function test() {
    log(Object.prototype.toString.apply(arguments));
    log(Object.prototype.toString.apply([]));
}

test();
// Will output:
// [object Arguments]
// [object Array]

We’ll come to what the apply function does later. For now, just note that arguments object’s type (i.e. Arguments) is different than the type of an array literal’s (i.e. Array).

Since arguments object is not an array, it does not contain any of the Array.protoype methods. So the following code will generate an error:

function createSentence() {
    log(arguments.join(' ')+'.');
}

// This will generate an error.
createSentence('Hello', 'world');

If we want to do array operations on arguments, we first need to convert it to an array. Let us modify the above code, so that it functions properly:

function createSentence() {
    log(Array.prototype.slice.call(arguments).join(' ')+'.');
}

createSentence('Hello', 'world');
// outputs:
// 'Hello world.'

Reflection

Function name, and length are nice tools to be kept in our utility belt. But they are worth nothing until we use the power of Function.prototype.call, and Function.prototype.apply:

fuction calculateLine(a, b, x) {
    log(this);

    return a*x + b;
}

var context = {lorem: 'ipsum'};

// This will log {lorem : 'ipsum'} and return 6.
calculateLine.call(context, 1, 2, 3);

// This will also log {lorem : 'ipsum'} and return 6:
calculateLinke.apply(context, [1, 2, 3]);

Both call, and apply work similarly: They dynamically bind a new context and a set of parameters to a given function. The only difference is that call expects a parameter list whereas apply requires an enumerable object (an array, or an array-like object like the arguments object).

Currying

Combining reflection with the concept of “higher order functions” gives us a set of useful general-purpose methods. One of them is curry:

Currying is the technique of transforming a function that takes multiple arguments in such a way that it can be called as a chain of functions each with a single argument.

Ref: http://en.wikipedia.org/wiki/Currying

Not clear? An example will clarify ;) .

Here’s the curry function from o2.methodhelper.core.js.

/**
 * @function {static} o2.MethodHelper.curry
 *
 * <p>Curries the <code>function</code>.</p>
 * <p>See http://www.dustindiaz.com/javascript-curry/ for a
 * discussion.</p>
 * <p>Usage Example:</p>
 * <pre>
 * function test(a,b,c) { return a+b+c; }
 * var curried = o2.MethodHelper.curry(this, test, 1, 2);
 * var result = curried(3);//returns 6;
 * </pre>
 *
 * @return the modified <code>function</code>.
 */
curry : function() {
    var args = Array.prototype.slice.call(arguments);
    var context = args.shift();
    var fn = args.shift();

    return function() {
        return fn.apply(context,
            args.concat(
                Array.prototype.slice.call(arguments)
            )
        );
    };
},

Currying is a very useful concept. Indeed, it is the foundation of an entire field of mathematics and computer science called lambda calculus.

Curry, simply fixes the first arguments of a function, and leaves the remaining arguments to be set later. This is can be used to create a specific version of a more general function.

Here’s an example to demonstrate the concept:

function getLinearCoordinate(a, x, b) {
    return a*x + b;
}

// Will compute y = 0*x + b; i.e.: y = b
var getConstantLine = o2.MethodHelper.curry(this, getLinearCoordinate, 0);

// This will give 5.
getConstantLine(10, 5);

// This will give 10.
getConstantLine(20, 10);

Partial Functions

Another variation of curry is partial functions.

First let us see the partial implementation of o2.methodhelper.core.js:

/**
 * @function {static} o2.MethodHelper.partial
 *
 * <p>Defines a partial <code>function</code>.</p>
 * <p>See http://ejohn.org/blog/partial-functions-in-javascript/ for a
 * detailed discussion.</p>
 * <p>Usage Example:</p>
 * <pre>
 * function test(a,b,c){ return a*b+c; }
 * var partial = o2.MethodHelper.partial(this, test, 10, undefined, 20);
 * var result = partial(3);//returns 50;
 * </pre>
 *
 * @param {Object} base - the context of the newly created
 * <code>function</code>.
 * @param {Function} fn - the <code>function</code> to modify.
 * @param {Arguments} varargin - variable number of input arguments to be
 * passed as initial set of arguments.
 *
 * @return the modified <code>function</code>.
 */
partial : function(base, fn) {
    var args = Array.prototype.slice.call(arguments);
    var context = args.shift();
    var fn = args.shift();

    return function() {
        var arg = 0;
        var i = 0;

        for (i = 0; i < args.length && arg < arguments.length; i++) {
            if (args[i] === undefined) {
                args[i] = arguments[arg++];
            }
        }

        return fn.apply(context, args);
    };
},

Partial, improves curry one level further, and enables us replace any set of arguments.

Let’s use the above getLinearCoordinate function and create a partial function out of it:

function getLinearCoordinate(a, x, b) {
    return a*x + b;
}

// Will compute y = 1*x + 0; i.e.: it's an identity function
var getIdentity = o2.MethodHelper.partial(this, getLinearCoordinate, 1,
    undefined, 0);

// This will give 15.
getIdentity(15);

// This will give 20.
getIdentity(20);

Argument Flipping

Instead of using partial functions, we can easily change the order of arguments in a function to make it suitable for our needs.

Let’s create another helper to flip any two arguments of a function:

me.flip = function(fn, index1, index2) {
    return function() {
        var temporary = arguments[index1];
        arguments[index1] = arguments[index2];
        arguments[index2] = temporary;

        return fn.apply(this, arguments);
    }
};

Flip often works together with curry:

function power = function(base, power) {
    Math.pow(base, power);
}

// Flip the first two arguments.
var powerFlipped = o2.MethodHelper.flip(power, 0, 1);

// Takes the cube of a given parameter.
var cube = o2.MethodHelper.curry(powerFlipped, 3);

// Returns 8.
cube(2);

Function Composition

When you are in the realm of functional programming, you have infinite number of possibilities around. The only thing that’ll take time is to acquire a habit of thinking in “function“s, instead of thinking in “object“s. Once you pass that boundary, a brand new world reveals itself to your feet.

Let’s create yet another function that kind-of “chains” two functions:

me.compose = function(invoker, fn) {
    return function() {
        return invoker.call(this, fn.apply(this, arguments));
    }
};

And here’s a sample usage:

var roundedPower = o2.MethodHelper.compose(Math.round, Math.pow);

// This will return 4.
roundedPower(3, 1.2);

Curry, is also a spice that goes well with compose.

var url = 'http://o2js.com/?s=samurai';
var substring = String.prototype.substring;
var indexOf = String.prototype.indexOf;
var compose = o2.MethodHelper.compose;
var curry = o2.MethodHelper.curry;
var kQuery = '?';

var getQueryString = curry(
    compose(substring, indexOf),
    kQuery
);

// This will return: '?s=samurai':
getQueryString(url);

Folding

Folding is running a function through a collection. The concept is similar to the reducer function, which is one of the building blocks of map-reduce paradigm, in distributed computing.

There’s a hell lot of theory behind implementing map-reduce methodology to a very large document oriented distributed data set. If you want to get experimental with those concepts you can try out one of the many open-source NoSQL databases around. My favorite is MongoDB as it’s agile, it uses JSON (actually BSON) in its document-oriented storage, it’s scalable and it’s syntactically “very” similar to JavaScript.

For the sake of this article though, let us simply focus ourselves with plain old JavaScript.

The folding concept can be better demonstrated with an example. First, let’s define a fold function:

me.fold = function fold(collection, fn, initial) {
    var args = Array.prototype.splice.call(collection, 0);
    var result = initial;
    var i = 0;
    var len = 0;

    for(i = 0, len = arg.length; i < len; i++) {
        result = fn(result, args[i]);
    }

    return result;
};

And now let’s define a product function:

function product() {
    return fold(arguments, function(a, b) {
        return a*b;
    }, 1);
}

And then use the function:

// This will return 120 (i.e. 1*2*3*4*5)
product(1, 2, 3, 4, 5);

Fold takes a collection, an evaluator function, and a starting seed value. It runs through all the elements of the collection. On each element it executes the evaluator function with the result of the previous evaluation as the first parameter, and the current element as the second parameter.

In other words, the data of the former calculation is fed back to the original function.

This behavior conceptually resembles a positive feedback loop that’s used to define a linear time-invariant system in control theory — but that’s also a whole other story :) .

Recursion

Recursion is a crucial aspect of functional programming. And an article on functional programming would be incomplete without mentioning recursion.

Recursion is a method of defining functions in which the function being defined is applied within its own definition.

Ref: http://en.wikipedia.org/wiki/Recursion

Recursion is basically a way of controlling flow.

Applying recursion over a large data set may cause a stack overflow exception. The stack overflow problem can be “mostly” alleviated by applying tail calls.

Let’s start with a simple example and write a function to traverse the DOM tree starting with a root node and applying a callback function for each node:

function traverseTree(rootNode, callback) {
    var children = rootNode.childNodes;
    var child = null;
    var i = 0;
    var len = 0;

    callback(rootNode);

    if (!rootNode.hasChildNodes()) {
        return;
    }

    for (i=0, len = children.length; i<len; i++) {
        traverseTree(children[i], callback);
    }
}

The traverseTree function recursively calls itself, until all the child nodes of the root node have been processed.

Theoretically, every recursive function can be written in a non-recursive way. Let’s try to write our node-traversal algorithm non-recursively:

function traverseNode(currentNode, callback, isCurrentDone) {
    var firstChild = null;
    var nextSibling = null;
    var parent = null;

    if (!isCurrentDone) {
        callback(currentNode);
        firstChild = currentNode.firstChild;

        if (firstChild) {
            return {currentNode: firstChild, isCurrentDone: false};
        }
    }

    nextSibling = currentNode.nextSibling;

    if (nextSibling) {
        return {currentNode: nextSibling, isCurrentDone : false};
    }

    return {currentNode: currentNode.parentNode, isCurrentDone: true};
}

function traverseTree(rootNode, callback) {
    var currentNode = rootNode;
    var isCurrentDone = false;
    var result = null;

    while (currentNode) {
        result = traverseNode(currentNode, callback, isCurrentDone);
        currentNode = result.currentNode;
        isCurrentDone = result.isCurrentDone;

        if(currentNode == rootNode) {
            break;
        }
    }
}

I leave figuring out the details of the above algorithm to the reader.

When writing functional code, recursion is generally preferred over writing loops.

Let’s try write the fold function recursively:

function fold(collection, fn, seed) {
    return (!!!collection.length) ?
        seed :
        fold(collection.splice(1), fn, fn(collection[0], seed));
}

function multiply(a, b) { return a * b; }

// This will return 24.
fold(multiply, [1,2,3,4], 1);

Recursion enables us write the function in a more compact way. Compare this new fold function with the fold function near the top of this article to see the difference.

Memoization

In computing, memoization is an optimization technique used primarily to speed up computer programs by having function calls avoid repeating the calculation of results for previously-processed inputs.

Ref: http://en.wikipedia.org/wiki/Memoization

Here is the memoize function from o2.methodhelper.core.js:

/**
 * @function {static} o2.MethodHelper.memoize
 *
 * <p><strong>Memoizes</strong> the given <code>function</code>'s outcome
 * and presents it from cache, instead of recalculating.</p>
 * <p>See http://en.wikipedia.org/wiki/Memoization for details.</p>
 * <p>Usage Example:</p>
 * <pre>
 * function multiply(a,b){return a*b; }
 * var memoized = o2.MethodHelper.memoize(multiply);
 * var result = memoized(2,3);//fresh calculation.
 * result = memoized(4,2);//fresh calculation.
 * result = memoized(2,3);//retrieve from cache.
 * </pre>
 *
 * @param {Function} fn - the <code>function</code> to memoize.
 * @param {Object} context - what should "this" refer to.
 * @param {...} ... - variable number of input arguments to pass
 * arguments to fn.
 *
 * @return a reference to the memoized <code>function</code>.
 */
memoize : function() {
    var pad = {};
    var args = Array.prototype.slice.call(arguments);
    var self = args.shift();
    var obj = args.length > 0 ? args[0] : null;

    var memoizedFn = function() {

        // Copy the arguments object into an array:
        // this allows it to be used as a cache key.
        var args = [];
        var i = 0;

        for (i = 0; i < arguments.length; i++) {
            args[i] = arguments[i];
        }

        // Evaluate the memoized function if it hasn't
        // been evaluated with these arguments before.
        if (!pad.hasOwnProperty(args)) {
            pad[args] = self.apply(obj, arguments);
        }

        return pad[args];
    };

    return memoizedFn;
},

Let’s observe the benefits of memoization with an example:

// Our good old "fold" function from the above example.
function fold(collection, fn, seed) {
    return (!!!collection.length) ?
        seed :
        fold(collection.splice(1), fn, fn(collection[0], seed));
}

// Just adds two items, nothing fancy.
function add(a, b) { return a + b; }

var run = function() {
    return fold([].slice.call(arguments), add, 0);
};

var runMemoized = o2.MethodHelper.memoize(run);

var ar = [];
var i = 0;
var begin = 0;
var end = 0;

// Prefill array with a large data set.
for (i=0; i<20000; i++) {
    ar.push(i);
}

begin = (new Date()).getTime();

// Compute run with the array.
runMemoized.apply(this, ar);

end = (new Date()).getTime();

log('First run: '+(end-begin)+' milliseconds.');

begin = (new Date()).getTime();

// Re-compute run with the same array.
runMemoized.apply(this, ar);

end = (new Date()).getTime();

log('Second run: '+(end-begin)+' milliseconds.');

// The output will have a output similar to this:
//
// "First run: 407 milliseconds."
// "Second run: 3 milliseconds."

We know that our function is deterministic, so we can use memoization. And since we’ve memoized the result of the first call, we do not need to recompute the output of the parameter set. Therefore the second computation is significantly (two orders of magnitude in this particular example) faster.

These are not the Constructors you are looking for…

This tip is also an answer I’ve given gave to a “JavaScript Engineer” job interview question I’ve had with a globally-known company.

The interviewer was basically asking me to create a static object, by using closures, to hide some of the implementation details of an object. That’s what the module pattern is for anyway :) .

Since we plan to create a static helper class to reside in the memory, a simple and efficient way of doing it would be something like this:

var Library = (function() {
    state = {
        lorem : 1,
        ipsum : 2
    }

    return {
        compute : function() {
            return state.lorem + state.ipsum;
        },

        setLorem : function(value){
            state.lorem = value;
        }
    };
}());

Library.setLorem(2);

// Will return 4:
Library.compute();

In the above code, “state” is internal to the closure, it is impossible to access it directly outside of it.

However the proposed solution I gave during the interview was, “kind of“, convoluted:

var Library = function() {
    state = {
        lorem : 1,
        ipsum : 2
    };

    return {
        compute : function() {
            return state.lorem + state.ipsum;
        },

        setLorem : function(value) {
            state.lorem = value;
        }
    };
};

var lib = new Library();
lib.setLorem(2);

// Will return 4:
lib.compute();

Where the Library constructor simply returns an object that is different from the Library instance itself.

This was a touchdown demonstration of a JavaScript kung-fu move, and the interview went extremely well. Yet I stumbled around, and had some hard time putting my reasoning into words during the interview :-| .

Since I have more time, if you bear with me, let me try to elaborate the concept, in depth, here:

According to Seciton 13.2.2. of ECMA 265 Edition 5.1, the object construction semantics is described as follows:

When the [[Construct]] internal method for a Function object F is called with a possibly empty list of arguments, the following steps are taken:

  • 1. Let obj be a newly created native ECMAScript object.
  • 2. Set all the internal methods of obj as specified in 8.12.
  • 3. Set the [[Class]] internal property of obj to “Object”.
  • 4. Set the [[Extensible]] internal property of obj to true.
  • 5. Let proto be the value of calling the [[Get]] internal property of F with argument “prototype”.
  • 6. If Type(proto) is Object, set the [[Prototype]] internal property of obj to proto.
  • 7. If Type(proto) is not Object, set the [[Prototype]] internal property of obj to the standard built-in Object prototype object as described in 15.2.4.
  • 8. Let result be the result of calling the [[Call]] internal property of F, providing obj as the this value and providing the argument list passed into [[Construct]] as args.
  • 9. If Type(result) is Object then return result.
  • 10. Return obj.

This is a mouthful way of saying the constructor returns the newly created object, if and only if the return value of the evaluated constructor function is NOT an object.

Constructor functions are strange kind of animals. If the constructor returns an object, the returned object is used instead of the original object. Otherwise, the return value is irrelevant, and the newly constructed object will be used.

A direct corollary to this is that it doesn’t matter whether you use “return“, or “return this” inside a constructor.

Hey, you can even store a reference to the original object and use it. Let’s make the above example even more convoluted by applying this concept ;) :

var Library = function() {
    this.state = {
        lorem : 1,
        ipsum : 2
    };

    var self = this;

    return {
        compute : function() {
            return self.getState().lorem + self.getState().ipsum;
        },

        setLorem : function(value) {
            self.getState().lorem = value;
        },

        setIpsum : function() {
            self.setIpsum.apply(self, arguments);
        }
    };
};

Library.prototype.getState = function() {
    return this.state;
}

Library.prototype.setIpsum = function(value) {
    this.state.ipsum = value;
}

var lib = new Library();
lib.setLorem(2);

// The getState method and will generate Type Error:
// TypeError: lib.getState is not a function
//lib.getState();

// setIpsum is revealed through reflection.
lib.setIpsum(5);

// Will return 7:
lib.compute();

This usage can be a clever way to encapsulate prototype functions inside the constructor.

In a Nutshell

Here’s a “five line summary” of what we have reviewed so far:

  • The whole philosophy of functional programming is to retain “referential transparency“, which requires writing deterministic functions that have no side-effects. In order to encourage this, variables should be immutable.
  • A “deterministic function” is a function that always gives the same output, given the same input.
  • Functional programming is a way to achieve anything by chaining deterministic functions to one another.
  • Partial evaluators (i.e. curry, partial) are the building blocks this chaining process.
  • In order to support partial evaluation, functions may need to translate or transform parameters into another function. This is called currying.

Conclusion

With great power, comes great responsibility ;) .

Extensively using reflection, delegation, closures, and dynamic context binding will create bugs that are virtually impossible to track.

Moreover, overuse of dynamic context binding (with method.apply and method.call), and using nested closures increase the depth of the execution scope. This can create performance and memory problems, if not handled correctly.

Yet, the power of higher order functions cannot be understated; and JavaScript provides a spectrum of capabilities to leverage them.

Hope you’ve enjoyed reading this article as much as I’ve enjoyed writing it :) .
I’d love to hear your comments and suggestions.
Feel free to share them below.

It's me: Volkan! Jack of all Trades, Samurai of JavaScript ;) Since 2003, I’ve been doing front-end development on client-heavy AJAX web applications. Currently, I'm a JavaScript Hacker at "SocialWire". Before that I was a VP of Technology at "GROU.PS", a well-known do-it-yourself social networking platform that allows people to come together and form interactive communities around a shared interest or affiliation. Before that, I was a JavaScript Engineer at "LiveGO", a globally known social mash-up. Before that, I was the CTO of a business network ("cember.net") which was acquired by Xing AG for around 4.2M Euros. See my linkedin profile to find more about me; I also share worth-following bits an pieces on twitter.

VIsit Volkan Özçelik's website

Leave a Reply





o2.js _
Fork Ribbon