Search code examples
javascriptfunctional-programmingpurely-functional

Pass a nested function as a parameter


Is there a way nest functions and pass them as a parameter? I have this 2 functions:

function mayus(string) {
    return string.toUpperCase();
}

function removeA(string) {
    return string.replace(/A/g, "");
}

and I want to apply them in 2 different ways

function stringHandler1(stringID) {
    var newString = mayus(removeA(getString(stringID))); 
    return newString;
}

function stringHandler2(stringID) {
    var newString = removeA(mayus(getString(stringID)));
    return newString;
}

The 2 stringHandlers return slightly different strings, but they are fairly similar. Is there a way to use one string handler that takes 2 parameters (the stringID and the operation)

function stringHandlerINeed(string, operation) {
    var newString = operation(string);
    alert(newString);
}

I want to do something like

stringHandlerINeed("516af2", mayus(removeA))

Update: I marked jJ' as the answer because it doesn't require me to change any of the functions I already have, and it's the concept I was looking for, but this answer by juvian is so simple makes me wish I had come up with it.


Solution

  • What you really want is probably function composition... one way to implement it is like this:

    function compose() {
        var fns = Array.prototype.slice.call(arguments);
        return function (arg) {
            fns.forEach(function (fn) {
                arg = fn(arg);
            });
            return arg;
        };
    }
    
    compose(mayus, removeA)('axA'); // -> "X"
    compose(removeA, mayus)('axA'); // -> "AX"
    

    There are endless applications of this concept. You can use any number of functions chained in compose. You can name the composed function:

    var mayusRemoveA = compose(mayus, removeA);
    

    You can also create a constant function (something like your handler above) instead of values that are evaluated by calling composed function directly...

    var theHandlerINeed = compose(function () { return 'axA'; }, mayus, removeA);
    
    theHandlerINeed(); // -> "X"