Introduction to Functional Programming

There is been quite hype around functional programming and its advantage, and its even known as an alternative to object oriented programming. We all have heard about various functional languages such as OCaml, Clojure, Haskell, and many languages such as Python, JavaScript, Scala provide functional programming techniques.

As the name suggests functions as considered first-class objects. Being first-class objects means that functions will be treated as objects in these languages. Functions can be dynamically built, stored in a variable and can even be passed around as parameters. This simply means functions are center of concern here rather than focusing on objects like in object-oriented programming. Functions talked here is directly derived from concepts of functions in mathematics. However these functions are different from typical method functions in imperative programming.

It’s important to compare these programming ways to identify the differences and identify correct usage of functional programming. Primary concern of functional programming is not ‘ how do do it ’ but rather ‘ what to do ’. Major difference could be identified as using declarative programming model in functional programming rather than it’s competitor’s imperative programming model.

There are some more difference such as using maps over loops as well as unimportance of execution order. Some of these differences will be discussed in following content.

Pure functions are used mainly in functional programming. Simply these functions are without side effects. Simply a function would take some input, process them as needed and return intended result. These pure functions consist of following properties to ensure their purity.

Immutable data structures are used in functional programming. Immutable data can not be modified and initially set values are final. As an example if we declare variable as int x = 10 , it wouldn't be changed with x = 12. So you would have to create new data structures instead of modifying existing ones.

Functions are stateless, meaning that functions should be depended on any external state or should not update any external states. If the function is not depended on any state, it will run identically for same input values. This means that it should always perform the task as if the first time. As this would not update any external states there wouldn’t be any side events because of this function.

Let’s first consider following imperative code block:

int x = 2function incrementOne(){
x++
}

print(x)

If we run incrementOne() we can see that would result in 3. However if we run incrementOne() again, it would result in 4. We can clearly see that the function incrementOne() is clearly dependent on some external state ( x as of here) and is not a pure function.

Let’s design above code from functional programming prospective:

int x = 2function incrementOne(int i){
return i++
}
print(incrementOne(x))

Here incrementOne(2) would result in 3 regardless of the number of times we run the function. Another fact to pay attention is that we are printing out incrementOne(x) and not x. Its because x is immutable and isn’t possible to change from value 2, and have to use new data structure like int y = incrementOne(x).

High order functions would take one or more functions as arguments and will return a function as result. Map is such higher order function accepting a function and a list of elements. It would apply input function to all elements of input list and return output list. Simply it’s like map( f(x) , listA ). As an example map( x => 2*x , [1,2,3,4]) would result in new array of [2,4,6,8] rather than adjusting values of input array. This map function is used instead of loops in functional programming to iterate over an array. Output array is taken by applying the function to each input element. Reduce and Filter are another notable higher order functions used in functional programming. Reduce function would combine elements of the array rather than iterative over them.

Lazy evaluation means that it would avoid evaluation till its value is actually needed. As an example when int x = multiply(3,4) it wouldn’t be set to 12 just yet. However if we want to print(x) value will be evaluate for usage. This is also useful when there are redundant functions to be evaluated. In this example int y = add( multiply(3,4) , multiply(3,4) ) evaluation involves repeated multiply(3,4) functions. Here due to lazy evaluation multiply(3,4) would be evaluated just one, since repetition of functions will be recognized.

Recursion over loops is used in functional programming. Pure functional languages would not support impure functions or mutable states. Here for simple for (int i=0 , i<10 , i++) loop we would be using mutable loop counter value of i. This is not acceptable for functional programming and will use recursive functions such as map or forEach for iterating over a list. Furthermore use of pure functions allows compilers to efficiently optimizing using methods such as tail call optimization.

Anyone familiar with recursion is aware of how factorial(n) works. However recursion can be substituted to just about anywhere with iterations. Here we can see an example of how recursion is used in calculating total of an array.

function totalOfArray( currentTotal, arrayA ){
currentTotal = add(currentTotal, arrayA[0])
remainingArray = arrayA.slice(1)

if(remainingArray.length >0){
return totalOfArray(currentTotal, remainingArray)
}
else {
return currentTotal
}
}

This recursion would keep on adding first element of the array in each function call. However currentTotal is passed to recursive function calls as a parameter avoiding any mutable placeholder. If we would have used loops we will be looping through for(int i=0, i < array_A.length, i++) and will be adding to an external global variable as this: total += arrayA[i]. This would violate immutability, stateless behaviour and purity of function.

Functional programming will provide more readable cleaner code. Scenarios such as usage of map function over looping statements are such examples. This would reduce complexity and improve readability of the code.

Parallel programming is encouraged through functional programming due to lack of mutable states. Numerous functions could be run concurrently and wouldn’t affect other functions or external state since these functions are without side effects. Evaluation of functions should be run concurrently to improve efficiency too.

Testing and debugging is easier with functional programming as we will be using pure functions. These functions should result in same output at all times regardless of the state, therefore we could simply compare inputs with output and confirm whether intended operation was performed.

However due to immutability there can be more memory usage. Each of the result of functions will be new objects. As an example if we want to get double of x = 10, in imperative programming we could just x = x * 2. The result will still be stored in x, only using one int memory space. However in functional programming double(x) result will be stored separately since of immutability and would result in two int memory spaces. So it is good to keep track of memory usage in writing functional programs.

Well, that’s an introduction to Functional Programming and its usage. Feel free to point out any issues regarding the articles as well as any suggestions. Cheers!!!

Full Stack Developer | BiBi

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store