Every day, we come across different programming languages that we use for specific purposes. A problem can be solved in multiple ways using different programs.
However, the approach we choose significantly affects the time and space complexity of the code, efficiency of development, and even the code’s readability for other programmers. Before getting deep into the subject, let’s understand what a programming paradigm means.
What is a Programming Paradigm?
A programming paradigm represents the fundamental style or methodology of computer programming. It provides a conceptual framework for writing and structuring the code in a specific language. While it’s true that this can influence the organization of code, it goes beyond that.
Paradigms provide different tools and strategies that can be used when solving problems, influencing factors such as the way tasks are divided, the nature of the data structures used, the types of operations that are implemented, and how tasks are coordinated.
Let’s explore the different types of programming paradigms. They are broadly classified into Imperative Paradigm and Declarative Paradigm, which are further subclassified as shown in the following diagram.
Each language has its own unique style and is often designed to favor a certain programming paradigm. However, many modern languages are multi-paradigm, meaning they incorporate features from several paradigms.
For instance, Python combines procedural, object-oriented, and functional programming paradigms. The language is usually coded using the imperative style but can use the declarative style if required.
Let’s examine each programming paradigm in detail.
Imperative Programming
Imperative programming is a programming paradigm that uses statements to change a program’s state. It’s concerned with describing how a program operates in a step-by-step manner.
When you go shopping, you usually write down the names of items you need before reaching the mall. Similarly, this paradigm consists of a list of programming statements.
Statements are executed, and the results are stored in variables. It is more of a line-by-line instruction given to the computer.
Let us understand imperative programming using a C++ program that gives us factorial of a number.
Example:
#include<iostream>
using namespace std;
int main(){
int n = 8; // number to find the factorial of
int fact = 1;
for(int i = 1; i <= n; i++){
fact *= i;
}
cout << "Factorial of " << n << " is : " << fact;
return 0;
}
Output:
Factorial of 8 is : 40320
In this example, we give a line-by-line task to perform by the computer with proper instructions. This type of paradigm takes the order of the steps into consideration because different arrangements can produce different results.
Imperative programming can be further divided into procedural, structured, and object-oriented programming.
Procedural Programming
This programming paradigm follows imperative programming with procedural calls. These calls direct the system to perform the required tasks.
Each procedure, also known as a function, can have multiple commands to be executed. The function, once defined, can be called as many times as needed to perform the same operation.
Procedural programming is considered the best for people starting to learn to code. Beginners can start with procedural programming as it is simple, efficient, requires less memory, and is easier to keep track of control flow.
Some languages that employ the procedural programming paradigm include:
- C
- Fortran
- Pascal
- COBOL
Example program in C:
#include <stdio.h>
// Function to calculate factorial
int factorial(int n) {
int fact = 1;
for(int i = 1; i <= n; i++){
fact *= i;
}
return fact;
}
int main() {
int n = 8; // number to find the factorial of
// Call to the function factorial
int result = factorial(n);
printf("Factorial of %d is : %d\n", n, result);
return 0;
}
Output:
Factorial of 8 is : 40320
Structured Programming
It is an imperative programming paradigm where we use nested loops, conditional statements, and subroutines to define the control flow of a program. This paradigm has a top-down implementation which promotes code readability and reusability. In commercial applications, this helps to reduce development time and increase code quality.
Structured programming uses control structures like loops (for, while), conditionals (if, switch), and subroutines to control the program’s flow. These structures enable programmers to write code that is easier to understand and modify, because they provide a clear, top-down control flow.
For instance, instead of using ‘goto’ statements which can lead to ‘spaghetti code’, structured programming encourages the use of loops and conditionals that make the program’s flow of control more predictable and easier to trace.
While structured programming improves the readability and organization of code, it can lead to more complex code structures in larger programs. It may also require more overhead in terms of planning and design compared to less structured paradigms.
However, this doesn’t necessarily mean that structured programming languages are less efficient in execution. The efficiency often depends on the implementation details and the specific problem being addressed.
Some of the languages that use Structured programming paradigms are:
- Algol 60
- PL/I
- Pascal
- Ada 83
- Modula
Object-Oriented Programming
This is the most widely used and most popular programming paradigm. Class, Abstraction, Encapsulation, Inheritance, and Polymorphism form the backbone of Object-Oriented Programming (OOP).
In this paradigm, every entity in the program is considered an object. Objects can have data associated with them called attributes and actions they can perform using methods.
OOP feature | Description |
---|---|
Abstraction | It helps in hiding unnecessary attributes while showing the ones required. |
Inheritance | It helps in establishing hierarchical relationships promoting code reusability. |
Polymorphism | It allows different objects to respond in different ways to the same input. |
Encapsulation | It is the binding of data into a single unit. |
Some of the languages that predominantly use the object-oriented programming paradigm are:
- Python
- Ruby
- Java
- C++
- Smalltalk
I have written a separate article on Objected-Oriented Programming in Python. Do check it out if you are interested.
Declarative Programming
Declarative programming is a programming approach that expresses a computation’s logic without discussing its control flow. The programmer must specify what the program must accomplish but need not specify how it must be implemented.
In other words, rather than dictating ‘how’ to achieve a goal, as is common in imperative programming, declarative programming focuses on ‘what’ needs to be achieved, leaving the specifics of ‘how’ to the underlying system or language implementation.
While you don’t have to specify ‘how’ to achieve something, the ‘how’ is still important – it’s just handled by the system or the language implementation, not the programmer.
The declarative programming paradigm is further divided into logic programming and functional programming.
Logic Programming
The logic programming paradigm uses logic-based statements to convey facts and rules. Logical inferences are made of instructions or logic statements to do computation. Atomic statements are built using these predicate statements.
While displaying relevant data, logic languages frequently rely on queries. Some of the specific uses of logic programming are natural language processing, database management, predictive analysis, etc.
Some of the languages that use logic programming paradigms are:
- Prolog
- Polka
- Vulcan
- Mercury
Example:
Let us take the statement, “Jimmy is a dog. All dogs are omnivores. So Jimmy is an omnivore”.
So in a Prolog code,
dog(Jimmy).
omnivore(X) :- dog(X).
The first line asserts that ‘Jimmy is a dog’. The symbol ‘:-‘ is read as ‘if’. So, the second line represents the logic rule ‘If X is a dog, then X is an omnivore’.
To test the program, we can ask if Jimmy is an omnivore.
?- omnivore(Jimmy)
Output:
true
Functional Programming
Functional programming is built upon the concept of mathematical functions and immutability. In this paradigm, programs are constructed by applying and composing functions. This style of programming promotes a strong separation of data and behavior, and it is particularly useful when dealing with problems that involve concurrency and parallelism, due to its inherent properties such as referential transparency and absence of side-effects.
Functional programming, unlike imperative paradigms, emphasizes the evaluation of expressions rather than execution of commands. The main focus is on ‘what’ computations should be performed rather than detailing ‘how’ to compute them. This emphasis on expressions and their evaluation, rather than on control flow statements, makes programs written in functional style inherently less stateful and more mathematical.
One advantage of functional programming is that it tends to be well-suited for concurrent and parallel execution, which can be advantageous in multi-threaded and multi-core environments. This is due to its emphasis on pure functions and avoidance of shared state, which can simplify the management of concurrent tasks.
However, it’s not accurate to say that the system ‘automatically finds the best solution’. Instead, the programmer uses functions and function composition to describe what the output should be for a given input, and the runtime environment executes these functions according to its implementation.
Functional programming often allows for more concise code. It is also easy to unit test and debug using functional programming.
One potential challenge when adapting to functional programming is the less frequent use of traditional control flow structures like ‘for’ and ‘while’ loops. Instead, functional programming often encourages the use of higher-order functions like ‘map’, ‘filter’, and ‘reduce’, as well as recursion. However, this is not necessarily a disadvantage, but rather a different way of thinking about program flow that may require some adjustment for those accustomed to imperative programming styles.
Example: Javascript code that prints “Hello World” 10 times using functional programming.
Array(10).fill("Hello World")
.forEach((msg) => console.log(msg));
Output:
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Hello World
Some of the languages that use Functional programming paradigms are:
- Purely functional programming languages: Haskell
- Multi-paradigm languages with functional programming support: JavaScript, Scala, Lisp, Erlang
Final Thoughts
Learning and applying different paradigms to your coding problems will help you understand how they can reduce complexity and improve the effectiveness of your solutions. As programmers become more experienced, they may find that different paradigms are better suited to different types of problems, and that being able to switch between paradigms as needed is a valuable skill.
If you are just starting out, you can begin with procedural programming. Explore the other types of paradigms after that. Learn and apply them to your problem statements and check how the complexities are reduced.
I hope you found the article useful. If you have any doubts, let me know in the comment section. Happy coding!
This was quite informative. Thank you so much for the info💪🏼💪🏼💯💯
Glad that I could help 🙂
Thanks so much this was so informative,have learnt a lot
You are so so great… I have been going round and round trying to understand this paradigm….
Your explanation is the best..
Thanknu so much
ASHWIN, Kudos to you, nice job here. Please keep it up. Am ready for collaboration.
Thanks man
Merci beaucoup, en tout cas c’est très instructif. Cela dit, entre les deux paradigmes de programmation, impératif et déclarative, je trouve que le paradigme impératif inclus l’autre.
Merci pour le commentaire
Salut Ashwin, j’ai beaucoup aimé cette article et ça m’a beaucoup aidé, cela dit j’ai pas bien compris la programmation procédurale et structuré, et fonctionnel et logique.
Tu as dit que la programmation fonctionnelle n’utilise pas de boucle mais JavaScript utilise, boucle while et for. Peut m’éclairer ?
Many modern languages including Javascript are multi-paradigm, meaning they incorporate features from several paradigms.