Table of Contents
Functional programming is a programming paradigm in which it is tried to bind each and everything in pure mathematical functions. It is a declarative type of programming style that focuses on what to solve rather than how to solve (aimed by the imperative style of programming).
Clojure, Common Lisp, Erlang, Haskell, and Scala are some of the notable programming languages following the functional programming approach. The programming paradigm is based on lambda calculus, which is briefly explained below:
Instead of statements, functional programming makes use of expressions. Unlike a statement, which is executed to assign variables, evaluation of an expression produces a value. Lambda calculus forms the basis of almost all of the functional programming languages in use.
Developed by Alonzo Church, Lambda Calculus is a framework for studying computations with functions. Anything that is computable using lambda calculus is computable. Amazingly, it can be labeled as the most succinct programming language of them all.
In terms of its computational ability, lambda calculus is similar to the Turing machine that laid the foundation for the imperative style of programming. To put lambda calculus in simple words, it is a theoretical framework that describes functions and their evaluation.
Functional Programming Concepts
There are 5 most important concepts pertaining to functional programming.
Pure functions have two important properties, they:
- Always produce the same output with the same arguments disregard of other factors. This property is also known as immutability
- Are deterministic. Pure functions either give some output or modify any argument or global variables i.e. they have no side-effects
Because pure functions have no side-effects or hidden I/O, programs built using functional programming are easy to debug. Moreover, pure functions make writing concurrent applications easier.
When the code is written using the functional programming style, a capable compiler is able to:
- Memorize the results
- Parallelize the instructions
- Wait for evaluating results
In the functional programming paradigm, there is no for and while loops. Instead, functional programming languages rely on recursion for iteration. Recursion is implemented using recursive functions, which repetitively call themselves until the base case is reached.
Variables once defined in a functional programming language aren’t allowed to change the value that they are holding throughout the execution of the program. This is known as referential transparency. It assures that the same language expression gives the same output.
Functional programs don’t have any assignment statements. For storing additional values in a program developed using functional programming, new variables must be defined. State of a variable in such a program is constant at any moment in time.
Referential transparency eliminates even the slightest chances of any undesired effects due to the fact that any variable can be replaced with its actual value during any point in the program execution.
Functions are First-Class and can be Higher-Order
Functions in the functional programming style are treated as variables. Hence, they are first-class functions. These first-class functions are allowed to be passed to other functions as parameters or returned from functions or stored in data structures.
A higher-order function is a function that takes other functions as arguments and/or returns functions. First-Class functions can be higher-order functions in functional programming languages.
Variables are Immutable
In functional programming, variables are immutable i.e. it isn’t possible to modify a variable once it has been initialized. Though we can create a new variable, modifying existing variables is not allowed.
The immutable nature of variables in a functional programming language benefits in the form of preserving the state throughout the execution of a program.
- Because pure functions don’t change any states and are entirely dependent on the input, they are simple to understand. The return value given by such functions is the same as the output produced by them. The arguments and return type of pure functions are given out by their function signature.
- Due to the nature of pure functions to avoid changing variables or any data outside it, implementing concurrency becomes efficacious
- Functional programming supports the concept of lazy evaluation, which means that the value is evaluated and stored only when it is required.
- Pure functions take arguments once and produce unchangeable output. Hence, they don’t produce any hidden output. They use immutable values, making debugging and testing easier.
- The functional programming style treats functions as values and passes the same to other functions as parameters. It enhances the comprehension and readability of the code.
- Immutable values combined with recursion might lead to a reduction in performance
- In some cases, writing pure functions causes a reduction in the readability of the code
- Though writing pure functions is easy, combining the same with the rest of the application as well as the I/O operations is tough
- Writing programs in recursive style in place of using loops for the same can be a daunting task
Often, functional programming languages are preferred to be used for academic purposes rather than commercial software development.
Nonetheless, several prominent programming languages following a functional programming paradigm, such as Clojure, Erlang, F#, Haskell, and Racket, are used widely for developing a variety of commercial and industrial applications.
WhatsApp makes use of Erlang, a programming language following the functional programming paradigm, to enable its mere 100+ employees to manage the data belonging to over 1.5 billion people.
Moreover, the functional style of programming is essential for various programming languages to lead in distinct domains. For example, R in statistics and J, K, and Q in financial analysis.
Some elements of functional programming are even used by domain-specific declarative languages such as Lex/Yacc and SQL for eschewing mutable values.
Generally, the functional programming paradigm is widely employed in:
- Applications aimed at concurrency or parallelism
- Carrying out mathematical computations
Other than pure functional programming languages, it is possible to establish the functional approach of programming in non-functional programming languages too. There are several books available on the topic.
C++11, C# 3.0, and Java 8 added constructs for facilitating the functional programming style. One of the most notable examples of an imperative programming language using the functional style of programming is the Scala programming language.
Though typically written in a functional style, Scala features the presence of side effects and mutable states. Hence, the programming language can be placed at an in-between state among the imperative and functional programming styles.