Functional Programming Basics Using Javascript

Introduction

This is the first blog of a series of blogs on functional Programming, I will briefly talk about Programming paradigms and then jump into describing functional programming concepts utilizing Javascript as it is one of the well known functional programming languages. Readers are encouraged to refer the references to get more insight into the concept.

Programming Paradigm

Programming paradigm is a framework for thinking a certain way about problems and the attendant tools to 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, and many more.

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 computation 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 side effect–free.

Functional programming cherishes the following values

Functions are First Class Things

Being able to store Functions in a variable, able to create functions dynamically, return them or pass them to other functions, which means we should treat it like any other first class objects in that language.

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 so can a function

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

A String can be created as need and so can a function

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

A String can be passed to a function so can a function

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

A String can be returned from a function 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, however let’s see a complex one.

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 does that modifies the state outside the function, for example:

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

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

Avoid Mutable State

Since functional programming favors pure functions, which can’t mutate data, it also makes heavy 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 that ok? And the answer is yes.

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

var s = "HelloWorld";

s.toUpperCase();
//=> "HELLOWORLD"

s;
//=> "HelloWorld"

Benefits?

  • Avoid confusion and makes program more correct: Some of the most difficult bugs to find in large systems occur when state is modified non-locally, by client code that is located elsewhere in the program.
  • Allows faster and easier 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 the experts find challenging

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

Recursion instead of explicitly looping

Recursion is the most famous functional programming techniques. 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 each pass through the function operates 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 providing for and 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 only 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 needed.

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

This opens the door for many possibilities: asynchronous execution, parallelization, and composition, just to name a few.

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

Take full benefits 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 the things it references. 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.

Characteristic

Imperative Approach

Functional Approach

Programming Style

Perform step-by-step tasks and manage changes in state

Define what the problem is and what data transformations are needed to achieve the solution

State Changes

Important

Non-existent

Order of Execution

Important

Not as important

Primary flow Control

Loops, conditionals, and functional calls

Function calls and recursion

Primary Manipulation Unit

Structures and class objects

Functions as first-class objects and data sets

Functional Libraries for JavaScript

There are tons of functional libraries out there for example; 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 workhorses of the functional method. In fact, they’re the epitome of what a pure function and what a higher-order function should be like; 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’re standard for browsers that implement ECMAScript 5.1, they only work on arrays. Each time it’s called, a new array is created and returned. The existing array is not modified. But 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 3, there more functions that can be plugged into nearly any functional application: forEach(),concat(), reverse(), sort(), every() and some().

JavaScripts’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 goes something like this: programming occurs when you write code to do something and metaprogramming occurs when you write code that changes the way that something is interpreted.

References

  1. Functional Programming Patterns in Scala and Clojure
  2. Becoming Functional
  3. Functional Programming for Java Developers
  4. Functional Programming in Scala
  5. Functional Programming in JavaScript
  6. Functional JavaScript
  7. Functional Python Programming
  8. Functional Thinking
  9. Seven Concurrency Models in Seven Weeks

Advertisements