Why Functional Programming is getting popular

Reading Time: 4 minutes

Functional programming usually described as a programming paradigm has been in software development since the earliest days but has taken on new importance in the modern era

Generally, functional programming means using functions to the best effect for creating clean and maintainable software. Function definitions are expressions that simply map inputs to outputs, rather than a sequence of statements that update the state of the application.

Here are the reasons for Why you should look into a functional style of coding, or perhaps switching to a completely functional programming language.

Functional Programming Benefits

  1. Pure functions are better than impure functions
  2. Pure functions are easier to test
  3. Functional programming leads to fewer bugs
  4. Function signatures are more trusted
  5. Concurrency is kept safe
  6. Recursion is simpler
  7. Immutability 

Pure functions

The ideal in functional programming is what is known as pure functions. A pure function is one whose results are dependent only upon the input parameters, and whose operation initiates no side effect, that is, makes no external impact besides the return value.

Because pure functions ensure that the state of the outside program isn’t altered, they are strictly better to write than impure functions where possible. In some cases, an impure function is necessary, however, for example, if you need to make a network call, interact with a database, or print data to the console.

Pure functions are easier to test

The lack of side effects makes pure functions very easy to test, as we only need to test that the inputs produce the desired outputs. We do not need to check the validity of any global program state in our tests of specific functions.

In addition, as all dependencies are provided as inputs, we can easily mock dependencies. In an impure setting, we would have to keep track of the state of some global dependency throughout all of the tests.

However, in a pure setting, we would simply provide all dependencies as input. We no longer have to worry about maintaining a global state throughout our tests, and we can now potentially provide different versions of dependencies to different tests.

This allows us to test functions while explicitly having control over the provided dependencies in each test.

Functional programming leads to fewer bugs

Debugging and writing code with fewer bugs becomes quite a bit easier with pure functions. Because each function is simply a mapping of inputs to outputs, a simple stack trace or print statement at each level will reveal with the problem. With imperative paradigms, you could have shared or mutable states almost anywhere else in the codebase that’s potentially causing the bug.

Function signatures are more trusted

var area = areaOfCircle(2.0)

def areaOfCircle(radius: Double): Double {

    return 3.14 * radius * radius

}

Technically this code will work. As long as everywhere I calculate the area of a circle I first update the global radius variable I’ll get the correct output. the problem is that examining the signature of the function doesn’t give the whole story. A pure function will have a signature that tells you all you need to know about its usage.

def areaOfCircle(): Double

//We can fix the problem by making the function pure:

def areaOfCircle(radius: Double): Double {

     3.14 * radius * radius

}

Concurrency is more easily kept safe

Pure functions are definitionally thread-safe. Code is thread-safe when we can guarantee that no two concurrent processes will be trying to access the same data at the same time. This is called a race condition and is one of the hardest kinds of bugs to pin down. Because pure functions never share a state with other sections of a program they can’t have race conditions.

For example, take the code from above again.

var area = areaOfCircle(2.0)

def areaOfCircle(radius: Double): Double {

    3.14 * radius * radius

}

If two separate threads are accessing the areaOfCircle function at the same time and altering the value of the radius, one process could easily overwrite the other’s value of radius and one thread ends up with the output that was intended for the other thread.

Recursion is simpler

A function that calls itself is known as a recursive function and this technique is known as recursion. A recursion instruction continues until another instruction prevents it.

Recursion avoids mutable states associated with loops. It is quite common in functional programming and provides a natural way to describe many Algorithms. Recursion is considered to be an important part of functional programming

object RecursiveFunction extends App {

    // Function define

     def fact(n:Int): Int=

     {

         if(n == 1) 1

         else n * fact(n – 1)

     }

        println(fact(3))

    }

Immutability

The literal meaning of Immutability is unable to change. In the Functional Programming world, we create values or objects by initializing them. Then we use them, but we do not change their values or their state. If we need, we create a new one, but we do not modify the existing object’s state.

Immutability in concurrent applications

Immutability is a big thing in a multithreaded application. It allows a thread to act on an immutable object without worrying about the other threads because it knows that no one is modifying the object. So the immutable objects are more thread-safe than mutable objects. If you are into concurrent programming, you know that immutability makes your life simple.

Conclusion

In this blog we have discussed functional programming and why it is one of the most popular paradigms and has taken great importance in the modern era.

Discover more from Knoldus Blogs

Subscribe now to keep reading and get access to the full archive.

Continue reading