Bits and pieces of Functional Programming

Something about Pure Functions

Bits and pieces of Functional Programming

Functional programming is just another programming paradigm like Object-Oriented Programming, procedural, etc. But OOP is like an imperative paradigm where we use statements to change the program's state. And FP is a particular type of declarative paradigm in which ideally a program species what is to be done instead of how to do it.

So what is Functional Programming and what the cover photo has to do with it

Functional Programming languages are based on lambda calculus. Where lambda calculus is a model of computation and it's a process for formalizing a method. We will talk about it some on another day as it's a topic on its own.

So, what is functional programming and what it is about - In Functional Programming, we try to bind everything into pure mathematical functions. We try to write functions here that do only one task and does not communicate with the outside world or any of the Global state to avoid side effects (we will talk about it later). At the end of everything, it boils down to Pure Functions. FP is all about packaging our code into separate chunks so that everything's well organized in each part of the code.

Goals of Functional Programming

Some of the Goals of Functional Programming is the same as OOP or any other paradigms

To make code:-

  1. Clear and Understandable Code.
  2. Easy to extend and maintain.
  3. Less Bugs
  4. keep it DRY (Don't repeat yourself).
  5. make code predictable

In functional programming, there is a separation between data over a program and the behavior of a program. All objects created in fp are immutable. We avoid things like shared state & we adhere to the principle of pure functions.

water-1761027_1280.jpg

What are Pure Functions ?

Simply, pure functions are functions that depend only on inputs provided to them. It must not depend on the outside world like the Global state or any other global variable.

  • Pure function always returns the same output for the same input even if we call it ∞ times. That is called Referential Transparency.
  • Pure functions don't produce side effects. In other words, it does not affect the outside world other than giving output.
  • It does not mutate the outside objects but outputs a new modified object.

Below is the difference between Pure and Impure functions.

Impure Function

const changeProfession = (person, newProfession) => {
    person.profession = newProfession;
    alert(`${person.name} is now ${person.profession}`);
}

let person = {
    name: "Himanshu",
    profession: "Web Developer"
}

changeProfession(person, "Photographer");
console.log(person); // {name: "Himanshu", profession: "Photographer"}

Pure Function

const changeProfession = (person, newProfession) => Object.assign({}, person, {profession: newProfession});

let person = {
    name: "Himanshu",
    profession: "Web Developer"
}

const newPerson = changeProfession(person, "Photographer");
console.log(newPerson); // {name: "Himanshu", profession: "Photographer"}
console.log(person); // {name: "Himanshu", profession: "Web Developer"}

In Impure function we created an object 'person'. Then we passed this object to change the 'profession' function. In this function we attempted several sins:

  • we mutated the original person, in this way we modified the global object which is against the rules of pure functions.
  • we didn't return any value, where a pure function must return a value.
  • generally, in pure functions, we cannot affect the outside world even by alert or console.log.

Now, In Pure function we have removed these holes from our code by not mutating our original state but returning a completely new and modified state. And we are not affecting the outside world except returning a value.

Why we should not mutate any outside Object or anything

As up there, we talked about the goals of FP. If we mutate our state, sometimes the code becomes unpredictable and it becomes more difficult for another developer and even for you after some time to understand what's happening there. Sometimes we change things the way we didn't intend to. Suppose, if we want to use the previous state in the future for other computations but we mutated the state somewhere and now we don't have it and we can't get it back. And unknowingly (due to complex codebase) when you were intended to use the previous one but other developer or possibly you have used that mutated state to compute those things. But now you are scratching your head for hours or even days because the code isn't behaving as you had expected. So, to stay away from these situations we should Not Mutate State.

So ultimately, a Pure Function has 2 characteristics:

  • No side effects.
  • Deterministic - should give the same output for the same input.

some more examples of impure and pure functions.

// Some Impure functions
let showDate = () => new Date();
let showOutput = () => console.log("Hello World");
let randomNumber = () => Math.random();
const getUserData = async (username) => {
  const response = await fetch(`https://api.github.com/users/${username}`);
  return await response.json();
}
getUserData('himanshu27tasveer').then(data => {
  console.log(data);
})

// Some Pure functions
let showDate = () => new Date(2011, 4, 2); //Pure
const add4 = (num) => num+4; //Pure
const makeAdjectifier = (adjective) => (name) => name + " is " + adjective;

let awesomify = makeAdjectifier("Awesome");

console.log(awesomify("Currying"));  // "Currying is Awesome"

First Class Functions

Have you ever heard things like, if a programming language treats certain functions as a First-Class Citizens then those are first-class functions?

But what does a first-class citizen means in programming ?

When a programming language treats function like an object or a variable then those we call First Class Functions. That means we can assign it to other variables or pass it to the function or it can be returned from a function. We can play with it just like any other variable.

const sayHello = function(){
   console.log("Hello");
}

sayHello();

In this example, we are invoking a function using a variable.

Higher Order Functions

In calculus, an example of a higher-order function is the differential operator d / d x, which returns the derivative of a function f.

If we pass a function to an operator, let's say integral or differential then we will be getting an integrated or differentiated function as an output. So, here these operators are acting like a higher-order function. Higher Order Function describes a mathematical concept on functions that operate on other functions. Functions that can either take a function as an argument or can return a function as a value are known as Higher-Order Functions.

const multiplier = (multiple) => {
    return function(num){
        return num * multiple;
    }
}

const triple = multiplier(3);

console.log(triple(9)) // 27

In the above code multiplier is taking an argument multiple and this function is returning an anonymous function which is again taking an argument num and returning num times multiple. Here, we can say that multiplier is a Higher Order Function because it is returning a function as a value.

Difference between First-class functions and Higher order functions

There might be some confusion to some of the people like both of them sounds the same then why there are different terminologies for them.......

They might sound the same but both of them are different. When we say a function is a first-class function that means either some variable is holding that function or it is passed in some function as an argument, or we can just play around with it just like other variables. When we call any function a Higher-order function then either it's accepting a function as an argument or it is returning a function as a value. So, we can say that a higher-order function either must accept the first-class function as an argument or return a first-class function.

These two things are closely related to each other. It's hard to imagine Higher Order Function without First Class Function and vice-versa. We can apply the concept of Higher-Order Functions in general like in mathematics but First Class Functions are specific to Functional Programming Only.

But in the end, however they are related to each other they will help you to attain things like immutability, purity, scalability, readability, modularity, etc.

Can everything be pure?

No. Suppose you are building a Todo app with react and you decide to make it fully functionally programmed but before doing that you must think, how are you gonna save the todos. To do that you have to change states, you have to make an HTTP call and you have to make a change in DOM after every operation. But all these things aren't possible if you want to use only concepts of Functional Programming.

The goal of Functional Programming is not to make everything pure but to minimize the side effects. Side effects and impurity is not necessarily bad but the goal is to organize our code in a way so that we can isolate these side effects & we have fewer chances and worries of bugs in our functional or pure part of code.

Isolate the side effects so that code is predictable and easier to debug.

Conclusion

With our pseudo-short discussion on Functional Programming, you have learned about Pure functions, Immutability, Higher-Order Functions, First Class functions, etc. Functional Programming helps you attain scalability, readability, modularity, and a lot of other things but we cannot say that the Functional Paradigm is better than any other paradigm or any paradigm is better than Functional. They all have different advantages and disadvantages. It all goes according to the use case. When you need a highly modular, highly readable, bug-free, etc code then you can go with Functional, but if you will need to preserve states and fetch things from outside like databases then you can use Object-Oriented Programming and if you doing shorter and simpler things then you can move forward with Procedural way. And in the end, it all depends upon you.

References

Anjana Vakil Akshay Saini Andrei Neagoie

All these things, I have learned from these amazing people. You must check them out too.

Thanks for reading this blog. This is my first blog. So, if you see any errors please excuse me and point me out for the same