DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Data Engineering
  3. Data
  4. Functional Programming Using JavaScript

Functional Programming Using JavaScript

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

Mohammad Nadeem user avatar by
Mohammad Nadeem
·
Apr. 18, 19 · Tutorial
Like (7)
Save
Tweet
Share
52.80K Views

Join the DZone community and get the full member experience.

Join For Free

This is the first blog of a series on functional programming. 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.

Image title

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.

Image title

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.

Image title

  • 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

    Image title

    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

    Image title

    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

    Image title

    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

    Image title

    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

    Image title

    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.

    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: 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."
    Functional programming JavaScript Data Types Data structure Data (computing)

    Published at DZone with permission of Mohammad Nadeem, DZone MVB. See the original article here.

    Opinions expressed by DZone contributors are their own.

    Popular on DZone

    • Monolithic First
    • Building Microservice in Golang
    • NoSQL vs SQL: What, Where, and How
    • DevOps for Developers: Continuous Integration, GitHub Actions, and Sonar Cloud

    Comments

    Partner Resources

    X

    ABOUT US

    • About DZone
    • Send feedback
    • Careers
    • Sitemap

    ADVERTISE

    • Advertise with DZone

    CONTRIBUTE ON DZONE

    • Article Submission Guidelines
    • Become a Contributor
    • Visit the Writers' Zone

    LEGAL

    • Terms of Service
    • Privacy Policy

    CONTACT US

    • 600 Park Offices Drive
    • Suite 300
    • Durham, NC 27709
    • support@dzone.com
    • +1 (919) 678-0300

    Let's be friends: