About functional programming and currying in JavaScript

Functional programming is a declarative paradigm, where side-effects are avoided and data is considered immutable to make the code easier to maintain and to reason about.

In JavaScript, functions are first-class objects, which means that they can be assigned to variables and passed as parameters to other functions.

This allows us to introduce the concept of Higher-order Functions (HoF). HoFs are functions that take a function as a parameter, optionally some other parameters, and return a function. The returned function is usually enhanced with some special behaviors. Let's look at a simple example where there is a function for adding two numbers and it gets enhanced with a function that first logs all the parameters and then executes the original one:

const add = (x, y) => x + y

const log = func => (...args) => {
    console.log(...args)
    return func(...args)
}

const logAdd = log(add)

A common technique in functional programming is currying. Currying is the process of converting a function that takes multiple arguments into a function that takes one argument at a time, returning another function. Manipulating functions like this allows for the creation of customized functions w/o having to write explicit definitions of them.

Let's look at an example to clarify the concept.

Let's start with the add function we have seen before and transform it into a curried function.

Instead of writing:

const add = (x, y) => x + y

We define the function like this:

const add = x => y => x + y

And we use it in the following way:

const add1 = add(1)
add1(2) // 3
add1(3) // 4

This is a pretty convenient way of writing functions because since the first value is stored after the application of the first parameter, we can reuse the second function multiple times.

Another example

let greetCurried = function(greeting) {
    return function(name) {
        console.log(greeting + ", " + name);
    };
};

Lets us create a new function for any type of greeting, and pass that new function the name of the person that we want to greet:

let greetHello = greetCurried("Hello");
greetHello("John");
greetHello("Mery");

We can also call the original curried function directly, just by passing each of the parameters in a separate set of parentheses, one right after the other:

greetCurried("Hi there")("Howard"); //"Hi there, Howard"
comments powered by Disqus