Simply put, functional programming is a programming style that relies exclusively on functions. The higher-order functions are the main things to consider in this case. A function that can take another function as an argument and return a function as a return element is called a higher-order function.
Such as -
def first_func(func, arg): return func(func(arg)) def add(x): return x + 5 print(first_func(add, 10))
In the example above, we first call the
first_func function and send it a function and a value according to its definition. The function I sent is the add function and value 10. On the other hand, I took that add function as a func argument in the
first_func function and called it more than once. Again,
func or add function takes an argument. So, for the first time, I send 10 of them during the execution, and the return is 15 and for the second time, I get that 15 and get the final 20 as the result.
With functional programming comes the issue of Pure and Impure functions. A pure function is a function that has no side effects and a function that returns something based on its argument value. Such as -
def pure_function(a,b): c = (2 * a) + (2 * b) return c res = pure_function(5,10) print(res)
In the above program,
pure_function takes two arguments and returns a value after running calculations on them. From start to finish, this function neither depends on any external value nor is it associated with changing any external value. It can be called a pure function.
my_list =  def impure_function(arg): my_list.append(arg) impure_function(38) print(my_list)
When a value goes into
impure_function at the top, that value is inserted into a list whose name is on the outside, my_list. The functional boundaries of this function are a little extra. This is called the impure_function.
Normally when a function is created using the
def keyword. It is automatically assigned to a variable by which it can be called next. On the other hand, string or integer type values can be easily created without assigning them to any variable. This feature can also be used for function (not assigning variables) and via lambda. Functions created in this way are called anonymous functions.
The use of Lambda is very effective when it is very simple to send a function of one line as an argument to another function later. That is when it seems pointless to define/create a function that works in one line with a different def.
lambda x, ya: x + ya. First, the lambda keyword is written and its arguments are written after a colon. For example, this lambda takes two arguments and adds them to the work -
def my_function(func, arg): return func(arg) print(my_function(lambda x: 2 * x, 5))
The example above
my_function takes a function and a value as arguments. Next, when we call
my_function and feel the need to send a function and a value in it, we send a lambda instead. As lambda x: 2 * x and 5 without sending the function. Meanwhile,
my_function executes lambda as a function and since that lambda function has an argument x, it forwards its received argument to 5.
Maps and filters are useful for various operations on lists and similar objects called iterable in Python. These are built-in functions.
The map function takes a function and an iterable as its argument. The sent function is applied to virtually every element of that iterable. It then returns the modified iterable survival at the end. Such as -
def make_double(x): return x * 2 marks = [101, 121, 201, 301] result = map(make_double, marks) print(list(result))
[202, 242, 402, 602]
In the example above, we first defined a simple function whose role is to return any number that comes close to it by doubling. Then we defined another list that has some numbers in it. Then we called the map function and sent the
make_double function as its first argument and the
my_marks list (iterable) as the second argument. The map function returns another iterable in the result variable which is actually twice the value of the previous list. Finally, before printing, I converted that iterable into a list and printed it.
The name of the filter function makes it clear that it filters something. This function removes some elements from an iterable given to it based on a prediction (predict is a function that returns a boolean value). Like maps, filters also take two arguments - a function and an iterable (list).
The filter removes all the elements for which the return or prediction of the function sent to it is false. The following example will make it clear -
def is_odd(x): return x % 2 != 0 marks = [101, 202, 301, 404, 501, 601] result = filter(is_odd, marks) print(list(result))
[101, 301, 501, 601]
is_odd function returns True if the value attached to it is True, and False returns otherwise. And we sent this function as the first argument of the filter. On the other hand, I sent marks as iterable. Now the filter function applies that function to every element in our list and when its return is False it removes the element and returns a new object at the end.
Also published here.