Functional Programming in JavaScript

Consider the JavaScript functions:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function pi_sum(n) {
    let total = 0, k = 1;
    while (k <= n) {
        total += 8 / ((4*k-3) * (4*k-1));
        k += 1;
    }
    return total;
}

function sum_cubes(n) {
    let total = 0, k = 1;
    while (k <= n) {
        total += k*k*k;
        k += 1;
    }
    return total;
}

function sum_naturals(n) {
    let total = 0, k = 1;
    while (k <= n) {
        total += k;
        k += 1;
    }
    return total;
}

These JavaScript functions have similar logic to the Python functions. They start with the function keyword followed by the function name. The arguments are listed within parentheses ( ). The statements that define what the function does are enclosed in curly brackets { }.

let is used to declare the variables total and k with initial values of 0 and 1 respectively. The while loop is used to iterate until k is less than or equal to n. The += operator is used to add the right operand to the left operand and then assign the result to the left operand. It’s similar to the Python code total = total + ....

In Python, you can perform multiple assignments in one line, like total, k = total + ..., k + 1, but in JavaScript you have to do it in separate lines.

These three functions clearly share a common underlying pattern. They are for the most part identical, differing only in name and the function of k used to compute the term to be added. We could generate each of the functions by filling in slots in the same template:

1
2
3
4
5
6
7
8
9
function name(n, term) {
    let total = 0;
    let k = 1;
    while (k <= n) {
        total += term(k);
        k += 1;
    }
    return total;
}

In this JavaScript function, <name> and <term> are replaced with name and term, respectively. name is the name of the function, and term is a function that’s passed as a parameter to the name function.

To use this function template in your code, replace name with the actual function name you want to use and define a term function to pass as an argument. For example:

1
2
3
4
5
function cube(k) {
    return k*k*k;
}

let sumCubes = (n) => name(n, cube);

Here, we define a function cube that returns the cube of its input, and we define sumCubes as a function that applies name to n and cube.

Please note that in JavaScript, we can define term function on the fly, without need to declare it separately, using arrow functions, like this:

1
let sumCubes = (n) => name(n, k => k*k*k);

The principle explained here is a central one in computer science, known as abstraction. Abstraction involves identifying patterns and creating a generic version of the code that can handle the identified pattern, this can reduce code redundancy and improve code readability.

In JavaScript, we could abstract these functions with higher-order functions:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function summation(n, term) {
    let total = 0, k = 1;
    while (k <= n) {
        total += term(k);
        k += 1;
    }
    return total;
}

function pi_term(k) {
    return 8 / ((4*k-3) * (4*k-1));
}

function cube_term(k) {
    return k*k*k;
}

function natural_term(k) {
    return k;
}

let pi_sum = (n) => summation(n, pi_term);
let sum_cubes = (n) => summation(n, cube_term);
let sum_naturals = (n) => summation(n, natural_term);

Here summation is a higher-order function that takes a number and a function as arguments. It applies the input function to generate the term to be added to the total in each iteration. pi_term, cube_term, and natural_term are functions that define the terms to be added for each of the specific sums. Finally, pi_sum, sum_cubes, and sum_naturals are generated by partially applying abstractSum to the term functions.