Function currying in JavaScript

In Mathematics and Computer Science, currying is the technique of converting a function that takes multiple arguements into a sequence of functions that each take a single argument.

For example, Given a function with 3 parameters, The curried version will take one argument and returns a function that takes the next argument, which return a function that takes the third argument. The last function returns the result of applying function to all of the arguments. we can do it for more or fewer parameters.

To see the benefit of currying we are going to write an example that is useful for logging, for now we're going to only console.log, you can further implement it for actual loggings like in server, or in any log file.

    function log (date) {
        return function (mode) {
            return function (message) {
                console.log(`[${date.getHours()}:${date.getMinutes()}] [${mode}] ${message}`)
            }
        }
    }

We can make it call like this

    log(new Date())("DEBUG")("some debug")
    // [HH:mm] [DEBUG] some debug

logNow() will be the partial of log with fixed first argument

    let logNow = log(new Date())

We can use it as

    logNow("INFO")("message")
    // [HH:mm] [INFO] message

Or

    let debugNow = logNow("DEBUG")

    debugNow("message")
    // [HH:mm] [DEBUG] message

See, we can easily generate a partial function for today's log when called with one argument (like log(date)) or two arguments (like logNow(mode)(message)).

The logNow function takes one arguement, and then returns a partial application of itself with date fixed in the Closure scope.

A Closure is a function bundled with its lexical scope. The Closures created at runtime while function creation.

Let's see another simple and beautiful example of currying using bind() method. we're going define a method which will add two numbers.

    function add (a, b) {
        console.log(a + b)
    }

Now we're going to create an increment method by using bind(), means any number we pass and it will increment it by 1.

    let increment = add.bind(this, 1)
    increment(5)
    // 6

See we didn’t lose anything after currying: add is still callable normally.

Similarly we can specialize number of method using currying, The method below will increment any number by 10.

    add.bind(this, 10)(5)
    // 15

References:

  • https://en.wikipedia.org/wiki/Currying
  • https://javascript.info/currying-partials
  • https://medium.com/javascript-scene/curry-and-function-composition-2c208d774983
Back to Home