Skip to content

SadhanaDeshmukh:Module4_FP

Sadhana Deshmukh edited this page Mar 22, 2023 · 6 revisions

What is functional programming?

  • There are three “types” of programming: procedural programming, object-oriented programming, and functional programming.
  • In object-oriented programming (OOP), we create “objects”, which are structures that have data and methods related to it.
  • In functional programming, everything is a function. Functional programming tries to keep data and behavior separate, and OOP brings those concepts together.

Rules of functional programming -

Data is immutable: If you want to change data, such as an array, you return a new array with the changes, not the original.
Functions are stateless: The function always gives the same return value for the same arguments.

Best practices that you should generally follow:

  1. Your functions should accept at least one argument.
  2. Your functions should return data, or another function.
  3. Don’t use loops.

Functional programming (FP) is an approach to software development that uses pure functions to create maintainable software. In other words, building programs by applying and composing functions.

Variables are Immutable:

  1. In functional programming, we can’t modify a variable after it’s been initialized.
  2. We can create new variables, but we can’t modify existing variables.
  3. This really helps to maintain state throughout the runtime of a program.
  4. Once we create a variable and set its value, we can have full confidence knowing that the value of that variable will never change.

Advantages:

  • Pure functions are easier to understand because they don’t change any states and depend only on the input given to them.
  • The ability of functional programming languages to treat functions as values and pass them to functions as parameters make the code more readable and easily understandable.
  • Testing and debugging is easier. Since pure functions take only arguments and produce output. They use immutable values, so it becomes easier to check some problems in programs written uses pure functions.
  • It is used to implement concurrency/parallelism because pure functions don’t change variables or any other data outside of it.

Disadvantages:

  • Sometimes writing pure functions can reduce the readability of code.
  • Writing programs in recursive style instead of using loops can be bit intimidating.
  • Writing pure functions are easy but combining them with the rest of the application and I/O operations is a difficult task.
  • Immutable values and recursion can lead to decrease in performance.

Important terms in functional programming

Immutability / Referential transparency:

  1. In functional programs variables once defined do not change their value throughout the program.
  2. Functional programs do not have assignment statements.
  3. If we have to store some value, we define new variables instead.
  4. This eliminates any chances of side effects.
  5. State of any variable is constant at any instant.
x = x + 1 // here value of x has been changed so,
// it is not referential transparent.

Function Composition:

  • Composition is the process of composing small units into bigger units that solve bigger problems.
  • Where Input of one function comes from the output of previous one.
  • It's the application of a function to the output of another function. e.g.
const deductTaxes = (grossSalary) => grossSalary * 0.8
const addBonus = (grossSalary) => grossSalary + 500

const netSalary = addBonus(deductTaxes(2000))

image

Deterministic Functions

A function is deterministic if, given the same input, it returns the same output. For example:

const joinWithComma = (names) => names.join(', ')

console.log(joinWithComma(["Shrek", "Donkey"])) 
console.log(joinWithComma(["Shrek", "Donkey"])) 

A common non-deterministic function is Math.random which will give a new value each time.

p2

Pure functions:

A pure function is a function that is deterministic and has no side effects. These functions have two main properties.

  • First, they always produce the same output for same arguments irrespective of anything else.
  • Secondly, they have no side-effects i.e. they do not modify any arguments or local/global variables or input/output streams called immutability. The pure function’s only result is the value it returns. e.g.
    function calculateGST( Price ) {
    return Price * 0.05;
    }
    console.log(calculateGST(15))

p3

Recursion:

  1. There are no “for” or “while” loop in functional languages.
  2. Iteration in functional languages is implemented through recursion.
  3. Recursive functions repeatedly call themselves, until it reaches the base case. e.g.
fib(n)
    if (n <= 1)
        return 1;
    else
        return fib(n - 1) + fib(n - 2);

Higher Order function:

The functions which take at least one function as parameter or returns a function as it results or performs both is called Higher Order Function. It is a great tool when it comes to functional programming. There are three important functions -

  • map()
  • filter()
  • reduce()

Program to double elements of an array
without map

const num = [10, 20, 30];
const num10 = [];
for(let i = 0; i < num.length; i++) {
  num10.push(num[i] * 2);
}
console.log(num10);

with map

const num = [10, 20, 30];
const num10 = num.map(i => i * 2);
console.log(num10);

p4

Program to check which students are present without filter

var students = [
  { name: 'John', status: true},
  { name: 'Micheal', status: false },
  { name: 'Ade', status: true },
  { name: 'Enuel', status: false },
  { name: 'Alamu',status: true },
];
var presentStudent= [];
for(let i = 0; i < students.length; i++) {
  if(students[i].status >= true) {
    presentStudent.push(students[i].name);
  }
}
console.log(presentStudent);

with filter-

var students = [
  { name: 'John James', status: true},
  { name: 'Micheal Obi', status: false },
  { name: 'Bola Ade', status: true },
  { name: 'Emmanuel', status: false },
  { name: 'Faithfulness Alamu', status: true },
];
var presentStudent =students.filter(student => student.status == true);
console.log(presentStudent);

p5

Reduce-
This method executes a callback function on every element in the array, which results in a single value. The method accepts two arguments:

  • Callback function
  • Initial value

Program to add number of an array without reduce

var numbers = [10, 29, 11, 43, 37];
let addition = 0;
for(let i = 0; i < numbers.length; i++) {
  addition = addition + numbers[i];
}
console.log(addition);

with reduce -

const numbers = [10, 29, 11, 43, 37];
const addition = numbers.reduce((sum, value) => sum + value, 10);
console.log(addition); 

p6

Arity

Arity is the number of arguments that a function takes.

var display = function(value)
{
    console.log (value);
}

var sum = function(first, second)
{
    console.log (first+second);
}
display(100)
sum(10,30)

p7

Currying

  • Currying is the transformation of a function with multiple arguments into a sequence of single-argument functions.
  • That means converting a function like this f(a, b, c, ...) into a function like this f(a)(b)(c)...
    Normally we write -
function isGreaterThan(a, b) {
  return b > a;
}

console.log(isGreaterThan(3,5))

By currying this program -

function isGreaterThan(a) {
  return function(b) {
    return b > a;
  }
}
console.log(isGreaterThan(3)(5))

p8

It is used when we want to reuse the created code or we know that one parameter is going to be fix and other will change accordingly.

function fun1(val1)
{
    return (val2) => {
        var c=1
        for(var i=0;i<val1;i++)
        c=c*val2
        return c;
    }
}
var square = fun1(2)
console.log(square(3));  //9
console.log(square(10)); //100

var cube = fun1(3)
console.log(cube(4)); //64
console.log(cube(10)); //1000

Here we can find multiple of any number by the same function.

Functors

A functor is simply something that can be mapped over. In OOP-speak, we’d call it a ‘Mappable’ instead. An array can be mapped over — you can map a function over an array as -

console.log([ 2, 4, 6 ].map(x => x + 3))

if we want to create a program to add anything by 1 then we may write something like this -

i1

And what if we want to perform this task by minus or subtraction operation as well. It will become much more complex. Which can be done in much more easy and effective way by using functors, like this-

i2

There are some more functors as well other than map, we have filter, reduce but forEach is not a functor because it take value for sure unwrap process the data but it does not returns anything that's why it is not a functor.

Closure

  • A closure is a feature of JavaScript that allows inner functions to access their outer scope.
  • Closure helps in binding a function to its outer boundary and is created automatically whenever a function is created.
function outer()
{
    var b = 1;
    function inner(){
        return b;
    }
    b=10;
    return inner;
}
var inner=outer();
console.log(inner());

p10