The Simple Guide to Programming Paradigms
Tags: computerscience, beginners, programming, theory
Published: 2021-07-26 05:44:38

I've published over 30 articles this past year, with that comes a lot of research and I've seen so many different programming paradigms that I just have to write about it. 

But before we begin, we first got to know what is a programming paradigm. 

## Table of Contents

- [Programming Paradigms](#programming-paradigms)
- [The Dark Ages](#the-dark-ages)
    - [Structured Programming](#structured-programming)
- [Imperative Programming](#imperative-programming)
    - [Procedural Programming](#procedural-programming)
    - [Object-Oriented Programming](#object-oriented programming)
- [Declarative Programming](#declarative-programming)
    - [Logic Programming](#logic-programming)
    - [Functional Programming](#functional-programming)
    - [Reactive Programming](#reactive-programming)
- [Conclusion](#conclusion)

## Programming Paradigms

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ij9stms106ts6ktycq5f.png)

As developers our number one enemy is complexity. 

I'm sure you've heard the term, "If I had more time, I would've made the program simpler". 

Because simpler code is more maintainable and can be easily debugged. 

In a nutshell: 

> Complexity is the enemy

To battle complexity, software developers have created different **programming paradigms or styles of programming**, similar to martial arts. It's not bound to a specific programming language, but some languages are more suited to one style.

Let's go over the history of these paradigms.

## The Dark Ages

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c056nmideoatd6uipcus.png)

The earliest known programming paradigm was called **non-structured**. It was barbaric due to the use of [goto](https://en.wikipedia.org/wiki/Goto) statements to literally jump to different areas of the code. 

It got the job done, but at what cost?

Unreadable or spaghetti code. 

Many people complained about the brutality of non-structured programming, it was horrible to maintain and debug. 

Until one day, a man by the name of [Edsger W. Dijkstra](https://en.wikipedia.org/wiki/Edsger_W._Dijkstra) advocated against using [goto](https://en.wikipedia.org/wiki/Goto) or equivalent. 

Thus creating his own style of programming called **structured programming** and ending the dark ages of non-structured.

### Structured Programming

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u3y4aorg9rbrh0umndil.png)

The school of structured programming brought many successes. 

Computer programs had more clarity, quality, and were made faster than ever. 

Structured programming advocated the use of structured control flow such as:

- **Conditionals** — `if/then/else`
- **Repetition** — `while/for`
- **Block Structures**
- **Functions**

They also completely rejected the use of dark arts, such as [goto](https://en.wikipedia.org/wiki/Goto) or its equivalent. 

Structured programming was the default, and many new programming languages were created with structured programming in mind. 

Eventually, structured programming advanced so much that it was too divided into two new styles.

## Imperative Programming

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zkasn2kvenilalfo6hsz.png)

The first of these new styles was imperative programming. 

Imperative programming is a programming paradigm that uses statements to change the programs state. It focuses on the **HOW** by showing you the solution step by step. 

For example, let's say we were tasked to return even numbers from a list of integers.

Imperatively we would solve it like this:

```jsx
const list = [1,2,3,4,5,6];
const result = [];

for(let i = 0; i < list.length; i++){
	if(list[i] % 2 == 0){
		result[] = list[i]
	}
}
```

Here we know exactly what's happening, we can simply follow the code, and see how the solution works. 

Within imperative programming, there are also another two inner-schools.

### Procedural Programming

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cxga2f90py7hqi1peufq.png)

Procedural programming is a subset of imperative programming where we split the step by step instructions into procedures. 

But what is a procedure?

A procedure is basically a function that **DOESN'T** return any value, and **ACHIEVES** some sort of side effect. 

A good example would be the classic loop in most programming languages. 

```jsx
const list = [1,2,3,4,5,6];
const sum = 0;

for(let i = 0; i < list.length; i++){
	sum += list[i]
}
```

It's essentially a function that doesn't return anything but causes side effects.

**Benefits of Procedural Programming:**

- Excellent for general-purpose programming
- Because of the simplicity of the code, it's easier to implement compilers and interpreters
- Simplicity
- Ability to be highly modular
- The memory requirement is slow, making it fast and efficient

**Languages that support Procedural Programming:**

- C
- C++
- Java
- Javascript
- Python

### Object-Oriented Programming

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4jxsbqqrur15uk4xg0vi.png)

Object-Orientated Programming is a subset of imperative programming where you structure your code in objects that can hold data (in form of fields) and code (in form of methods).

Object-Oriented Programming is by far one of the most popular and widely used programming paradigms in our times. 

There are four main principles in Object Orientated Programming:

- **Encapsulation** - Binds data and it's related methods together within a class. It also protects the data by making fields private and giving access to them only through their related methods.
- **Abstraction** - It's the concept of object-oriented programming that "shows" only essential attributes and "hides" unnecessary information.
- **Inheritance** - It's the mechanism of basing an object or class upon another object or class, retaining similar implementation.
- **Polymorphism** - It's the ability of an object to take on many forms.

I have another article, with an in-depth explanation for each of these principles. 

You can read it here.

{% post https://dev.to/tamerlang/oop-principles-for-dummies-2mbd %}

**Benefits of Object Orientated Programming:**

- Reusability due to inheritance
- Flexibility due to Polymorphism
- Security due to Encapsulation and Abstraction
- Lower costs due to reusability

**Languages that support Object-Oriented Programming:**

- Java
- C++
- Python
- PHP

## Declarative Programming

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k95ro2boqd5ubefikcr6.png)

On the other hand of the spectrum we have declarative programming, it also comes from structured programming but unlike imperative programming where it focuses on the **HOW**, declarative programming focuses on the **WHAT**. 

An example of a declarative programming language would be SQL (Structured Query Language). 

So let's say for example you want to get all rows from a table called `users`

```sql
SELECT * FROM users
```

You don't really care how `SELECT` works, you simply want to get all users. 

Similar to imperative programming, declarative programming also has four inner schools.

### Logic Programming

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qmkqdzzxxnidmwwkla2p.png)

Logic Programming is a programming paradigm based on formal logic. Meaning that you have a bunch of facts/statements, and you get new statements that comply with the original facts.

A classical example would be:

- Socrates is a Man
- All Men Are Mortal

From these two statements, we can conclude that Socrates is also mortal. 

But how is this expressed in code?

Take a look at an example made in Prolog:

```prolog
man(Socrates).
mortal(X) :- man(X).
?- mortal(Socrates).
```

Let's break this down:

1. The first line expresses that Socrates is a man. 
2. The second line says "X is mortal if X is a man". 
3. The third line is our question that says "Is Socrates mortal?" which will return `yes`.

**Benefits of Logic Programming:**

- Simple to write code
- Easy to debug
- Fast development
- Ideal for expressing complex ideas and algorithms
- Allows data to be represented both extensionally and intentionally

**Languages that support Logic Programming:**

- Prolog
- Absys
- ALF (algebraic logic functional programming language)
- Alice
- Ciao

### Functional Programming

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a4c7ggnxprtu8i8s3m9m.png)

Functional Programming is by far the most used declarative programming paradigm, the basic premise is that programs are constructed by applying and composing functions. 

Let's take a look at this example:

```jsx
// Generating a Fibonnaci sequence
fib(n)
    if (n <= 1)
        return 1;
    else
        return fib(n - 1) + fib(n - 2);
```

Functional Programming has to follow a set of principles:

- **Pure Functions** — All functions must be pure, meaning that it should have no side effects and it should be deterministic, returns the same result if given the same arguments
- **Immutability** — When data is immutable, its state cannot change after it’s created. If you want to change an immutable object, you can’t. Instead, you create a new object with a new value.
- **Referential Transparency** — Basically because we got pure functions and immutability, we can replace all function calls with their underlying return values and the program would still work.
- **Functions as First-Class Entities** — It means that functions can be passed to other functions as arguments.
- **Higher-Order Functions** — Higher-Order functions are basically functions that accept other functions as arguments and returns a function as its result.

**Benefits of Functional Programming:** 

- It helps us to solve problems effectively in a simpler way.
- Improves modularity.
- Allows us to implement lambda calculus to solve complex problems.
- Reduces complex problems into simple pieces.
- Debugging is easy.

**Languages that support Functional Programming:**

- Haskell
- JavaScript
- Scala
- Erlang
- Lisp
- Clojure

### Reactive Programming

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xjjzfjz1wzbuxwr0z237.png)

Reactive programming is a programming paradigm that is concerned with data streams, and how it reacts to it. 

For example, you can have multiple streams (also called observers)

- Click events
- HTTP requests
- Ingested messages
- Availability notifications

For each stream, you have a subscriber that responds accordingly.

**Benefits of Reactive Programming:**

- Simple to do asynchronous work
- Avoid “callback hell”
- Simple to compose streams of data
- Simplifies complex threading
- Cleaner and maintainable code
- Easy to implement back-pressure

**Languages that support Reactive Programming:**

- Scala
- Haskell
- Elm
- Javascript

## Conclusion

There aren't all the programming paradigms available, there are many others I couldn't cover in this article. But I covered the main ones at the least, and I hope you have a better understanding of each. 

Thanks for reading, and don't forget to follow me on Twitter.