JavaScript the Fun Part


functional-programming-javascript

function-as-first-class-citizen


Okay, we are at the beginning of five essential concepts in FP. Of course I mean in bottom-up approach, because in top-down approach it would be category theory, functor, etc.

These five things are:

  1. function as first class citizen
  2. closure
  3. currying
  4. partial application
  5. composition

and these five concepts will depend upon each other. Understanding first (= function as first class citizen) is required to understand the second one (= closure) and so on.

variable

We all are familiar with variables and how to use them.f

// const language = "JS";
console.log( language );            // JS
console.log( language.length );     // 2

We store our data in variables and then pass them around as arguments to some functions to do some operations and those data and return back a result.

function

What is it?

In the simplest form: a block of code for execution by () operator.

function add( a, b ){
    return a + b;
}

// using add without () operator does nothing
// but with it we invoke the function
const r = add( 2, 3 );
console.log( r ); // 5

In non-function programming we just have this feature with a function. In C programming we can pass the address of a function to other function, but it becomes hard to use it heavily in the entire application.

Nor can we declare an inner function to use it, or return it just like what we do with a variable.

cpp example

Here is a simple add function in C++.

#include <iostream>

int add( int a, int b ){
    return a + b;
}

int main(){
    const int r = add( 3, 2 );
    std::cout << "add( 2, 3 ) === " << r << std::endl;
}

/* output
add( 2, 3 ) === 5
*/

It works perfectly. Lets make a change by adding an inner function to add function..

#include <iostream>

int add( int a, int b ){
//    return a + b;

    int sum(){
        return a + b;
    }

    const int r = sum();
    return r;
}

int main(){
    const int r = add( 3, 2 );
    std::cout << "add( 2, 3 ) === " << r << std::endl;
}

/* output of: g++ ./example.cpp -o cpp && ./cpp
temp.cpp: In function ‘int add(int, int)’:
temp.cpp:6:14: error: a function-definition is not allowed here before ‘{’ token
     int sum(){
              ^
temp.cpp:10:19: error: ‘sum’ was not declared in this scope
     const int r = sum();
                   ^~~
*/

Notice this line

a function-definition is not allowed here before ‘{’ token

which simply means we cannot declare an inner function, so we would be able to return it and use it latter.f

In this paradigm function is not a first class citizen. It cannot do what a variable does. But in FP paradigm it can.

Lets do the same with JavaScript.

function add( a, b ){
    function sum(){
        return a + b;
    }
    const r = sum();
    return r;
}

const r = add( 3, 2 );
console.log( r );   // 5

So it worked with no error, since we can do what we can do with variables in JavaScript.

refactoring

You may say why did you use sum() function? You did not have to do so! Yes, but think of it in this way, maybe we want to return a function not a variable.

function add( a, b ){
    return function sum(){
        return a + b;
    }
}

const r = add( 3, 2 ); // it returns a function
console.log( r() );   // 5

So as you can see if we have a function as first class citizen, we can use it just like a variable.

This crucial feature enables us to have / create other powerful features.

In next post we will talk about closure which is a feature based on this feature.


Update: Sat Nov 02 2019 09:06:59 GMT+0330 (Iran Standard Time)