Functional programming is a way of thinking about software construction based on some fundamental, defining principles. Functional programming is used in situations where we have to perform lots of different operations on the same set of data.
Functional programming is a programming paradigm in which we try to bind everything in a pure mathematical functions style. It is a declarative type of programming style. Functional programming focuses on “what to solve”, in contrast to an imperative style where the main focus is “how to solve. Before Object-Oriented programming, the software industry completely depended on functional programming. This paradigm helped the software industry for a couple of decades.
Functional code tends to be more concise, more predictable, and easier to test than imperative or object-oriented code — but if you’re unfamiliar with it and the common patterns associated with it, functional code can also seem tough, and the related theory can be a nightmare to newcomers. But if you’ve been programming in JavaScript for a while, chances are good that you’ve used a lot of functional programming concepts & utilities in your real software.
Programming languages that support functional programming — Haskell, JavaScript, Scala, Erlang, Lisp, ML, Clojure, OCaml, Common Lisp, Racket.
Functional programming languages are categorized into two groups, i.e. −
- Pure Functional Languages — These types of functional languages support only functional paradigms. For example − Haskell.
- Impure Functional Languages — These types of functional languages support functional paradigms and imperative-style programming. For example − LISP.
Characteristics of functional programming:
Pure functions
A pure function is a function in which given the same inputs, always returns the same output for the same arguments irrespective of anything else, and they have no side-effects, i.e. they do not modify any argument or global variables or output something. The pure function only result is the value it returns.
Pure functions have a property called referential transparency in which you can replace a function call with its resulting value without changing the meaning of the program, which is important in functional programming.
When the code is written in pure function style, a smart compiler can do many things, like it can parallelize the instructions, wait to evaluate results when needing them and memorize the results since the results never change as long as the input doesn’t change.
Recursion
There are no “for” or “while” loops in functional languages. Iteration in functional languages is implemented through recursion. Recursive functions repeatedly call themselves until it reaches the base case. Immutability rules out the use of imperative constructs like for, while, etc. Instead, we use recursion for iteration.
Side effect constructs:
In functional programs, variables, once defined, do not change their value throughout the program. Functional programs do not have assignment statements. If we have to store some value, we define new variables instead. This eliminates any chances of side effects because any variable can be replaced with its actual value at any point of execution. The state of any variable is constant at any instant.
Side effects are mostly avoided in functional programming, which makes the effects of a program much easier to understand, and much easier to test.
Side effects include:
- Modifying any external variable or object property (e.g., a global variable or a variable in the parent function scope chain)
- Logging to the console
- Writing to the screen
- Writing to a file
- Writing to the network
- Triggering any external process
- Calling any other functions with side-effects
Functions are First-Class and can be Higher-Order
First-class functions are treated as the first-class variable. You can create functions, save them to variables, pass them to other functions, and return them from another function or store them in data structures.
Higher-order functions are the functions that take other functions as arguments, and they can also return functions. Higher-order functions are often used to create utilities that can act on a wide variety of data types. It can also help to partially apply a function to its arguments or create a curried function for the purpose of reuse or function composition. These functions are also used to make a list of functions and return some composition of those input functions.
Variables are Immutable
In functional programming, an immutable object is a variable that can’t be modified after it’s created. This pretty well rules out global variables. In Functional programming, we can easily create a new Data structure, but we can’t modify the existing one, and this really helps to maintain the state throughout the runtime of a program. Once we create a variable and set its value, we can have full confidence knowing that the value of that variable will never change.
Shared State
Shared state is any variable, object, or memory space that exists in a shared scope or as the property of an object being passed between scopes. A shared scope can include global scope or closure scope. Often, in object-oriented programming, objects are shared between scopes by adding properties to other objects. Functional programming avoids shared states — instead of relying on immutable data structures and pure calculations to derive new data from existing data.
Advantages Of Functional Programming:
- It helps us to solve problems effectively in a simpler way.
- Pure functions are easier to understand because they don’t change any states and depend only on the input given to them. Their function signature gives all the information about them, i.e. their return type and their arguments.
- It improves modularity.
- Functional programming does not support state, so there are no side-effects results, and we can write error-free codes.
- It allows us to implement lambda calculus in our program to solve complex problems.
- Testing and debugging are easier with the help of pure functions and immutable variables.
- Some programming languages support nested functions that improve the maintainability of the code.
- It is used to implement concurrency/parallelism because pure functions don’t change variables or any other data outside of it.
- It reduces complex problems into simple pieces.
Disadvantages Of Functional Programming:
- For beginners, it is difficult to understand. So it is not a beginner-friendly paradigm approach for new programmers.
- Sometimes writing pure functions can reduce the readability of code.
- Maintenance is difficult during the coding phase when the project size is large.
- Writing programs in a recursive style instead of using loops can be a bit intimidating.
- Reusability in Functional programming is a tricky task for developers.
- Immutable values and recursion can lead to a decrease in performance.
- Functional programming requires a large memory space. As it does not have a state, you need to create new objects every time to perform actions.
It can be a completely new programming paradigm for the ones who are new to the programming field(definitely new for me). But I still hope this article was helpful for you in getting the basic ideas on functional programming.
This Functional programming concept might be tricky and tough. It will eventually become easier when you get into it deeply and start practising. Then you can enjoy the features of functional programming.