Of Closure and Currying

Recursion has always been a difficult concept for me to wrap my head around. Consequently, Closure in Javascript is also difficult to understand. Here's a brief series of exercises on Front End Masters, written here mostly to organize my thoughts and try to cement the concepts I've learned.

Consider the following function that takes an argument, and returns a function that returns that argument:

const identityf = arg => {
    return function(){
        return arg
    }
}

This is possible because of Closure, in which the context of an inner function includes the scope of the outer function. Nested functions can see block variables. On the back end, this involves using the heap instead of the stack to allow child functions to operate once the parent function is exited.

Things get more complex when you return functions:

// A function that takes a binary function, and makes it callable with two invocations
// For instance, calling liftf(multiply) (5) (6) would return 30
const liftf = func => {
    return function (first) {
        return function (second) {
            return func(first, second);
        };
    };
}

The reason that the multiple invocations(the (5) and (6) in the comments above) are possible is that the function is itself returning functions, and subsequent invocations are passed as arguments to the child functions. Multiple returns don't break the function because again, the child functions can operate even after the parent functions exit.

The process of breaking down functions with multiple arguments into a chain of single return functions is known as currying.

// This function takes a binary function and an argument, and returns a function that can take a second argument

const curry = (binaryFunction, arg) => {
    return function(secondArg){
        return binaryFunction(arg, secondArg);
    };
}

curry(add,2)(7); // is equal to 9