Now that you have learned about the paradigm shift to functional programming, let’s go into the depths of the fundamentals concepts that power functional programming. The comprehension of these basic concepts is important to create high-quality functional programming applications. You may be tempted to directly begin coding but these concepts can help you become a better coder.
1- Pure Functions
In functional programming, everything is seen as a function. Each function has to be “pure”. Pure here refers to two basic capabilities:
No Side Effects
A function can never be pure if it carries even a single side effect. A side effect is a property when a function’s states are modified by other functions. By states, we mean the data like variables or data structures. Pure functions do not carry any side effects; hence their memory or I/O operations can’t be affected. Now, you might wonder that why exactly does their presence considered bad. Well, because they make functions “unpredictable” where a function has to rely on its system’s state.
On the contrary, if a function’s state cannot be changed, then the same output is generated for the given input. A side effect of a function can also mean to write any operation which has been applied to the disk or turning on/off a control of your front-end UI’s function.
Same Result with Multiple Calls
Whenever a function is called without any modifications in its arguments, the same results are generated. Consider an example where you have designed a simple function “multiply (4, 5). Now, this function is expected to generate the same results .i.e. for each invocation. However, if you were programming in other paradigms then random functions or global variables may not allow your result to remain the same.
Pure functions also offer “memoisation”. Memeoisation refers to a technique in which pure functions’ output (always same result) is saved in the cache memory. Now, whenever such functions are invoked, caching helps to enhance the performance and speed of the application.
2- Higher Order Function
The concept of a function which is higher order is known in mathematics as well as computer science. Generally, they possess two fundamental characteristics.
Return Type
The return type of a higher-order function has to be a function. For example, review the following code in Java.
package fp;
public class higherOrderfunction {
public static void main(String args[]) {
System.out.println(A(4));
}
static int marks() {
int a=5;
return a;
}
static int A(int total) {
total =4;
return total+marks();
}
}
To simplify things, we have constructed a simple function marks. This function holds an integer value “a” which is returned. Now, we have a function A. A takes an argument for an integer total and assigns it a value. Now, comes the actual part. See how in return, we have used marks method as a return type. Since we have processed our function by returning another function; hence this function is a higher-order function.
Arguments
Another characteristic of a higher-order function can be its use of functions as input parameters. For instance, see this see pseudo-code:
Public areaRect (lb) // Here areaRect represents a function that takes arguments from another function lb to calculate length and breadth
{
int area;
area =l*b;
return lb; //
}
This function is a higher-order function because it processes itself using another function as a parameter.
3- First Class Functions
After higher-order functions, we have first-class functions. These are not too dissimilar to higher-order functions. It is important to note that a first-class function always adheres to the terms and conditions of a higher-order function. So what this means is that a first-class function has to return another function as well as contain a parameter in the form of function. Hence, by default, all first-class functions are higher-order functions. So what exactly is the difference between them? Well, context matters!
By referring a language to have support for first-class functions, we generally mean that uses its functions as values that can be easily passed around.
On the other hand, the term higher-order is more associated with the mathematics outlook when pure problem-solving requires a more theoretical and general perspective of the problem.
4- Evaluation
Some languages support strict evaluation while others offer non-strict evaluation support. This evaluation is targeted at the language’s processing of an expression while considering the function parameters or arguments. To familiarize yourself better with the concept, check this simple example:
Print length([4-3,4+6,1/0,7*7,3-8])
When a programming language uses non-strict evaluation to process this expression, then it simply returns back a value of 5 .i.e. the total number of elements. Such evaluation does not concern itself with the depth of values.
On the other hand, the same expression returns an error with strict evaluation because it found the third element “1/0” to be incorrect. Hence, this means that strict evaluation is more stringent and processes an expression more deeply.
In a few scenarios, non-strict evaluation has to enforce processing of strict evaluation when a function needs to be evaluated on a “stricter” basis due to an invocation.
5- Referential Transparency
In functional programming, the usual assignment of values is not offered. Variables are immutable; a value defined once is the final one which is not possible to be changed in future. It is the property which makes them without any side-effects. To understand further, consider the following example, where the value of x is changed after each evaluation.
x=x*15
In the start of the program, x was assigned a value of 1. The first evaluation made it 15.
Now, in the second evaluation, the value of x changes to 225.
Now, this function is not referentially transparent because the value of x is continuously changing.
So now, if we go by the functional concepts, then our example can be altered into this pseudocode:
int sum(int x)
{
x=x+2;
}
This type of function ensures that the value of x remains constant and it cannot be altered implicitly.