## Accelerators

### Go to Overview

KDP KDSP

PremonR Studio9

#### TechHub

Akka Scala Rust Spark Functional Java Kafka Flink ML/AI DevOps Data Warehouse

## Insights # Functional Programming with Python

## What is Functional Programming?

“Functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data”. In other words, functional programming (FP) promotes code with no side effects and immutable variables. It is a declarative type of programming style. Its main focus is on “what to solve” in contrast to an imperative style where the main focus is “how to solve”.

## Functional Programming Concepts

#### 1. Pure Functions

Pure functions have two properties:

a) They create no side effects.
b) They always produce the same output if given the same input. This means that the function cannot depend on any mutable state.

Side effects can be caused due to the following reasons :-

• Changing data that exists outside the function’s scope.
• Changing the value of arguments in the function.
• Throwing an exception or halting with an error.
• Printing to the console or reading user input.
• Reading from or writing to a file.

Let’s look at an example of Impure Function.

``````num2 = 3
# Adds two numbers, but uses the global `num2` variable.
return num1 + num2

``````

Let’s now look at the pure function of adding two numbers.

``````# Adds two numbers, using the arguments passed to the function.
return num1 + num2

``````

#### 2. Immutability

In functional programming, we can’t change the value of a variable after it has been initialized. This means if we need to change values in a list, we need to create a new list with updated values rather than changing the existing one. In FP, the immutable nature of variables helps by preserving the state throughout the execution of a program. In Python, data types such as int, float, complex, string, tuple, frozen set, bytes are immutable.

``````#  id() function returns a unique id for the specified object.
num1 = 21
print(id(num1))

num1 = 12
print(id(num1))

-----------------------------------------------------------------------------------
OUTPUT:

1705703664
1705703520
``````
``````tuple1 = (0, 1, 2, 3)
tuple1 = 4
print(tuple1)

-----------------------------------------------------------------------------------
OUTPUT:

Traceback (most recent call last):
File "D:/LeetCode/FP.py", line 2, in <module>
tuple1 = 4
TypeError: 'tuple' object does not support item assignment

Process finished with exit code 1``````

#### 3. Recursion

In FP, we avoid if-else statements or loops as it creates different outputs on each execution. Functional programs use recursion in place of loops for all the iteration tasks. Recursion is a function which calls itself again and again until an exit condition is met.

``````# returns factorial of a number
def factorial(num):

if num == 1:
return 1
else:
return num * factorial(num - 1)

print(factorial(5))

``````

#### 4. Functions are First-Class and can be Higher-Order

In FP, functions are treated as a data type and can be used like any other value. You can assign functions to variables, store them in data structures, pass them as arguments, or use them in control structures. For example, we can populate an array with functions, pass them as parameters, or store them in variables.

``````def cube(number):
return number * number * number

my_cube = cube  # Assigning function as an object
print(my_cube(5))

numbers = [21, my_cube(5), 12]  # Storing function in list
print(numbers)

# Returning function from another function
def display_numbers():
return my_cube(5)

print(display_numbers())
``````

A function is called a higher-order function if it contains other functions as a parameter or returns a function as an output.

Map, Filter and Reduce are some of the built-in higher order functions in Python.

##### Higher Order Function — Map

The map function takes two arguments. The first argument is a function and the second is iterable. It then applies the passed function to each item in the iterable.

``````num = [1, 2, 3, 4, 5]
# returns square of each element in the list.
square = list(map(lambda number: number ** 2, num))
print(square)

-------------------------------------------------------------------------------------------
OUTPUT:

[1, 4, 9, 16, 25]
``````
##### Higher Order Function — Filter

The filter function allows you to easily extract matching records from a larger set of data based on the criteria you provide. It takes two arguments. The first argument is a function and the second is iterable. The filter function returns a sequence from those elements of iterable for which function returns true.

``````num = [1, 2, 3, 4, 5]
# returns even numbers from list.
even = list(filter(lambda number: number % 2 == 0, num))
print(even)

-------------------------------------------------------------------------------------------
OUTPUT:

[2, 4]``````
##### Higher Order Function — Reduce

The reduce function accepts a function and a sequence and returns a single value which is calculated as follows:

1. Initially, the function is called with the first two items from the sequence and the result is returned.
2. The function is then called again with the result obtained in step 1 and the next value in the sequence. This process is repeated until each item in the sequence is iterated.
``````from functools import reduce

return num1 + num2

-------------------------------------------------------------------------------------------
OUTPUT:

10``````

• Pure functions always produce the same output and have no external values affecting the end result. Due to this programs are easier to test and debug.
• We can write efficient parallel or concurrent programs because they run independently without changing state.
• It supports the concept of lazy evaluation, which means we evaluate the value and store them only when it is needed.
• Unlike OOP, FP supports better Encapsulation with Pure Functions.
• As FP programs are made up of pure functions, we can reuse them very easily.