Understand functional programming concepts utilizing JavaScript, one of the most recognizable functional programming languages.

I will briefly talk about programming paradigms, then jump into describing functional programming concepts utilizing JavaScript, as it is one of the most recognizable functional programming languages. Readers are encouraged to refer to the references section for further insight into this fascinating concept.

Programming Paradigms

A programming paradigm is a framework for thinking about the problems and the attendant tools to help implement that vision. Many modern languages are polyparadigm (or multiparadigm): they support a number of different programming paradigms, such as object orientation, metaprogramming, functional, procedural, etc.

Functional Programming Paradigm

Functional programming is like a car powered by hydrogen fuel cells—advanced, futuristic, and not yet widely used. In contrast to an imperative program, which consists of a series of statements that change global state when executed, a functional program models computations as the evaluation of expressions. Those expressions are built from pure mathematical functions that are both first-class (can be manipulated like any other value) and free from side effects.

Functional programming cherishes the following values:

Functions Are First Class Things

We should treat functions like any other first class object in the language. In other words, storing functions in a variable, creating functions dynamically, and returning or passing them to other functions. Let’s take a look at an example below.

  • A string can be stored in a variable so can a function

var sayHello = function() { return “Hello” };

  • A string can be stored in an object field and so can a function

var person = {message: “Hello”, sayHello: function() { return “Hello” }};

  • A string can be created as needed and so can a function

“Hello ” + (function() { return “World” })(); //=> Hello World

  • A string can be passed to a function and so can a function

function hellloWorld(hello, world) { return hello + world() }

  • A string can be returned from a function and and so can a function

return “Hello”;

return function() { return “Hello”};

Do It at a Higher Order

Functions that take other functions as arguments or return them as results are called Higher-Order functions. We have already seen an example of this. Now let’s review it in a complex situation.

Example #1

[1, 2, 3].forEach(alert);

// alert box with "1" pops up

// alert box with "2" pops up

// alert box with "3" pops up

Example #2

function splat(fun) {

   return function(array) {

        return fun.apply(null, array);

   };

}

var addArrayElements = splat(function(x, y) { return x + y });

addArrayElements([1, 2]);

//=> 3

Favor Pure Functions

Pure functions are functions that have no side effects. A side effect is an action that the function creates, modifying the state outside the function. For example:

  • Modifying a variable.
  • Modifying a data structure in place.
  • Setting a field on an object.
  • Throwing an exception or halting with an error.

A simple example of this is a math function. The Math.sqrt(4) function will always return 2. This does not use any hidden information such as a state or settings. A math function will never inflict side effects.

Avoid Mutable State

Functional programming favors pure functions, which can’t mutate data, and therefore creates a need for the substantial use of immutable data. Instead of modifying an existing data structure, a new one is efficiently created.

You may wonder, if a pure function mutates some local data in order to produce an immutable return value, is this okay? The answer is yes.

Very few data types in JavaScript are immutable by default. Strings are one example of a data type that can’t be changed:

    var s = "HelloWorld";

    s.toUpperCase();

    //=> "HELLOWORLD"

    s;

    //=> "HelloWorld"

Benefits of Immutable State

  • Avoids confusion and increases program accuracy: Some of the most difficult bugs to find in large systems occur when state is modified externally, by client code that is located elsewhere in the program.
  • Establishes “quick and easy” multithreaded programming: If multiple threads can modify the same shared value, you have to synchronize access to that value. This is quite tedious and error-prone programming that even experts find challenging.

Software Transactional Memory and the Actor Model provide a direction to handle mutations in a thread safe way.

Recursion Instead of Explicitly Looping

Recursion is the most famous functional programming technique. If you don’t know by now, a recursive function is a function which calls itself.

The classic functional alternative to an iterative loop is to use recursion, where we pass through the function operating on the next item in the collection until a termination point is reached. Recursion is also a natural fit for certain algorithms, such as traversing a tree where each branch is itself a tree.

Recursion is very important to functional programming in any language. Many functional languages go so far as to require recursion for iteration by not supporting while loop statements. This is only possible when tail-call elimination is guaranteed by the language, which is not the case for JavaScript.

Lazy Evaluation Over Eagerly Computing

Mathematics defines some infinite sets, such as the natural numbers (all positive integers). They are represented symbolically. Any particular finite subset of values is evaluated only on demand. We call this lazy evaluation (also known as non-strict evaluation, call-by-need and deferred execution). Eager evaluation would force us to represent all of the infinite values, which is clearly impossible.

Some languages are lazy by default, while others provide lazy data structures that can be used to represent infinite collections and strictly compute a subset of values on demand.

It’s clear that a line of code that states result = compute() is calling for result to be assigned to the returned value by compute(). But what result actually equates to does not matter until it is required.

This strategy can result in a major increase in performance, especially when used with method chains and arrays. These are the favorite program flow techniques of the functional programmer.

This opens the door for many possibilities including asynchronous execution, parallelization, and composition.

However, there’s one problem. JavaScript does not perform Lazy evaluation on its own. That being said, libraries exist for JavaScript that simulate lazy evaluation efficiently.

Take Full Benefit of Closures

All functional languages include closures, yet this language feature is often discussed in almost mystical terms. A closure is a function that carries an implicit binding to all the variables referenced within it. In other words, the function encloses a context around what it is referencing. Closures in JavaScript are functions that have access to the parent scope, even when the parent function has closed.

   function multiplier(factor) {

      return function(number) {

          return number * factor;

      };

   }

  var twiceOf = multiplier(2);

    console.log(twiceOf(6));

//=> 12

Prefer Declarative Over Imperative Programming

Functional programming is declarative, like mathematics, where properties and relationships are defined. The runtime figures out how to compute final values. The definition of the factorial function provides an example:

factorial(n = 1 if n = 1

    n * factorial(n-1) if n > 1

The definition relates the value of factorial(n) to factorial(n-1), a recursive definition. The special case of factorial(1) terminates the recursion.

var imperativeFactorial = function(n) {

    if(n == 1) {

        return 1

    } else {

        product = 1;

        for(i = 1; i <= n; i++) {

              product *= i;

        }

        return product;

     }

}

var declarativeFactorial = function(n) {

       if(n == 1) {

             return 1

       } else {

             return n * factorial(n - 1);

      }

  }

The declarativeFactorial might look “imperative" in the sense that it implements a calculation of factorials, but its structure is more declarative than imperative.

The imperativeFactorial uses mutable values, the loop counter, and the result that accumulates the calculated value. The method explicitly implements a particular algorithm. Unlike the declarative version, this method has lots of little mutation steps, making it harder to understand and keep bug free.

Functional Libraries for JavaScript

There are tons of functional libraries out there: underscore.js, lodash, Fantasy Land, Functional.js, Bilby.js, fn.js, Wu.js, Lazy.js, Bacon.js, sloth.js, stream.js, Sugar, Folktale, RxJs etc.

Functional Programmer’s Toolkit

The map(), filter(), and reduce() functions make up the core of the functional programmer’s toolkit; a collection of pure, higher-order functions that are the workhorse of the functional method. In fact, they’re the epitome of what a pure function and higher-order function should emulate; they take a function as input and return an output with zero side effects.

These JavaScript functions are crucial to every functional program. They enable you to remove loops and statements, resulting in cleaner code. While they are standard for browsers implementing ECMAScript 5.1, they only work on arrays. Each time it is called, a new array is created and returned. The existing array is not modified. But wait, there’s more…They take functions as inputs, often in the form of anonymous functions referred to as callback functions. They iterate over the array and apply the function to each item in the array!

myArray = [1,2,3,4];

newArray = myArray.map(function(x) {return x*2});

console.log(myArray); // Output: [1,2,3,4]

console.log(newArray); // Output: [2,4,6,8]

Apart from these three, there more functions that can be plugged into nearly any functional application: forEach(), concat(), reverse(), sort(), every(), and some().

JavaScript’s PolyParadigm

Of course JavaScript is not strictly a functional programming language, but instead facilitates the use of other paradigms as well:

  • Imperative programming: Programming based around describing actions in detail.
  • Prototype-based object-oriented programming: Programming based around prototypical objects and instances of them.
  • Metaprogramming: Programming manipulating the basis of JavaScript’s execution model. A good definition of metaprogramming is stated as: “programming occurs when you write code to do something and metaprogramming occurs when you write code that changes the way that something is interpreted.”

Thanks for reading ❤

#javascript #web-development

Functional Programming Using JavaScript
1 Likes21.80 GEEK