Programming paradigms

In this article we're going to take a look at programming paradigms, a fancy title to describe popular ways or styles to organize your programming.

I will try to break it down into parts and give a simple explanation of each paradigm. This way you can understand what people are talking about when they say OOP, functional, or declarative.

What is a programming paradigm?

Programming paradigms are like different styles of building and organizing computer programs. Just like there are different ways to write a story or paint a picture, programming paradigms provide different ways to write code.

Think of it this way: Imagine you have a set of building blocks, and you can use those blocks to create different structures. Each programming paradigm is like a different set of rules or instructions for how to use those blocks.

For example, one programming paradigm might say to build a program by giving step-by-step instructions, like a recipe. Another paradigm might say to organize the program around different objects, like building with Lego blocks. Yet another paradigm might focus on using functions or mathematical concepts to solve problems.

These paradigms provide guidelines for how to structure your code, what tools or techniques to use, and how to think about solving problems. They help programmers write code in a consistent and organized way.

Different programming paradigms have their own advantages and are suited to different types of problems. Some paradigms are good for organizing large projects, while others are better for solving specific types of problems. The choice of which paradigm to use depends on the problem you're trying to solve and personal preference.

In simple terms, programming paradigms are just different ways to approach writing code, like different styles of building or creating things.

Now that we have introduced what programming paradigms are and are not, let's go through the most popular ones, explain their main characteristics, and compare them.

Keep in mind that this list is not complete. There are other programming paradigms that are not covered here, although I will cover the most popular and widely used ones.

Imperative Programming

Imperative programming consists of sets of detailed instructions that are given to the computer to execute in a given order. It's called imperative because as programmers we dictate exactly what the computer has to do, in a very specific way.

Imperative programming focuses on describing how a program operates, step by step.

Say you want to bake a cake. Your imperative program to do this might look like this:

- Pour flour in a bowl
- Pour a couple eggs in the same bowl
- Pour some milk in the same bowl
- Mix the ingredients
- Pour the mix in a mold
- Cook for 35 minutes
- Let chill

Here's an example of imperative programming in Python:

# Imperative Programming Example in Python

def calculate_sum(numbers):
    # Initialize sum variable
    sum = 0
    
    # Iterate over each number in the list
    for num in numbers:
        # Add the number to the sum
        sum += num
    
    # Return the calculated sum
    return sum

# Example usage
numbers_list = [1, 2, 3, 4, 5]
result = calculate_sum(numbers_list)
print("Sum:", result)

In this example, we have a function calculate_sum that takes a list of numbers as input and calculates their sum. The approach used here is imperative programming.

The function iterates over each number in the list using a for loop. Inside the loop, the current number is added to the sum variable. After iterating through all the numbers, the final sum is returned.

The example demonstrates the step-by-step process of calculating the sum, explicitly stating how to achieve the desired result. Imperative programming focuses on describing the exact sequence of operations and how to change the program's state to accomplish a specific task.

When you run this code, it will output the sum of the numbers in the list, which in this case is 15.

Procedural Programming

Procedural programming is an extension of imperative programming that incorporates the use of functions, which are also referred to as procedures or subroutines.

Following our cake example, procedural programming may look like this:

function pourIngredients() {
    - Pour flour in a bowl
    - Pour a couple eggs in the same bowl
    - Pour some milk in the same bowl
​}

function mixAndTransferToMold() {
    - Mix the ingredients
    - Pour the mix in a mold
​}

function cookAndLetChill() {
    - Cook for 35 minutes
    - Let chill
}

pourIngredients()
mixAndTransferToMold()
cookAndLetChill()

Here's an example of procedural programming in Python:

# Procedural Programming Example in Python

def calculate_sum(numbers):
    # Initialize sum variable
    sum = 0

    # Iterate over each number in the list
    for num in numbers:
        # Add the number to the sum
        sum += num

    # Return the calculated sum
    return sum

def calculate_average(numbers):
    # Calculate the sum using the calculate_sum function
    sum = calculate_sum(numbers)

    # Calculate the average by dividing the sum by the number of elements
    average = sum / len(numbers)

    # Return the calculated average
    return average

# Example usage
numbers_list = [1, 2, 3, 4, 5]
result = calculate_average(numbers_list)
print("Average:", result)

In this example, we have two functions: calculate_sum and calculate_average. These functions follow a procedural programming approach.

The calculate_sum function calculates the sum of a list of numbers using a for loop, similar to the imperative programming example. It iterates over each number in the list and adds it to the sum variable.

The calculate_average function utilizes the calculate_sum function to calculate the sum of the numbers. It then divides the sum by the length of the list to calculate the average.

The example demonstrates the use of functions or procedures to break down the problem into smaller, reusable parts. Procedural programming focuses on organizing code into procedures or routines that perform specific tasks.

When you run this code, it will output the average of the numbers in the list, which in this case is 3.0.

Object-Oriented Programming

One of the most popular programming paradigms is object-oriented programming (OOP).

The core concept of OOP is to separate concerns into entities which are coded as objects. Each entity will group a given set of information (properties) and actions (methods) that can be performed by the entity.

OOP makes heavy usage of classes (which are a way of creating new objects starting out from a blueprint or boilerplate that the programmer sets). Objects that are created from a class are called instances.

Following our pseudo-code cooking example, now let's say in our bakery we have a main cook (called Frank) and an assistant cook (called Anthony) and each of them will have certain responsibilities in the baking process. If we used OOP, our program might look like this.

// Create the two classes corresponding to each entity
class Cook {
	constructor constructor (name) {
        this.name = name
    }

    mixAndBake() {
        - Mix the ingredients
    	- Pour the mix in a mold
        - Cook for 35 minutes
    }
}

class AssistantCook {
    constructor (name) {
        this.name = name
    }

    pourIngredients() {
        - Pour flour in a bowl
        - Pour a couple eggs in the same bowl
        - Pour some milk in the same bowl
    }
    
    chillTheCake() {
    	- Let chill
    }
}

// Instantiate an object from each class
const Frank = new Cook('Frank')
const Anthony = new AssistantCook('Anthony')

// Call the corresponding methods from each instance
Anthony.pourIngredients()
Frank.mixAndBake()
Anthony.chillTheCake()

Here's an example of object-oriented programming (OOP) in Python:

# Object-Oriented Programming Example in Python

class Circle:
    def __init__(self, radius):
        self.radius = radius

    def calculate_area(self):
        # Calculate the area of the circle using the formula: pi * r^2
        area = 3.14 * (self.radius ** 2)
        return area

    def calculate_circumference(self):
        # Calculate the circumference of the circle using the formula: 2 * pi * r
        circumference = 2 * 3.14 * self.radius
        return circumference

# Example usage
circle1 = Circle(5)
area = circle1.calculate_area()
circumference = circle1.calculate_circumference()

print("Area:", area)
print("Circumference:", circumference)

In this example, we define a Circle class that represents a circle object. The class has attributes such as radius, and methods such as calculate_area and calculate_circumference.

The __init__ method is a special method called a constructor, which is invoked when a new Circle object is created. It initializes the radius attribute with the given value.

The calculate_area method calculates the area of the circle using the formula π * r^2, where r is the radius. The calculate_circumference method calculates the circumference of the circle using the formula 2 * π * r.

We create an instance of the Circle class called circle1 with a radius of 5. We then call the calculate_area and calculate_circumference methods on circle1 to calculate the area and circumference of the circle.

The example demonstrates the principles of encapsulation and abstraction in OOP, where data and methods are encapsulated within a class, and objects are created from the class to interact with the data and perform operations.

When you run this code, it will output the calculated area and circumference of the circle with a radius of 5.

Declarative Programming

Declarative programming is a programming paradigm that focuses on describing what needs to be accomplished, rather than explicitly detailing how to achieve it. In declarative programming, you specify the desired result or outcome, and the programming language or framework takes care of the implementation details.

In declarative programming, you define a set of rules, constraints, or relationships, and the program's execution is driven by these declarations. It emphasizes expressing the logic of a program without specifying the control flow explicitly. This approach allows for a more concise and abstract representation of the problem domain.

Declarative programming is often contrasted with imperative programming, where the emphasis is on specifying the step-by-step instructions or commands that the computer needs to execute to solve a problem.

Some examples of declarative programming languages and frameworks include SQL for querying databases, regular expressions for pattern matching, Prolog for logic programming, and HTML/CSS for describing the structure and style of a web page.

Declarative programming can provide benefits such as increased readability, modularity, and maintainability. It allows developers to focus on the problem domain rather than low-level implementation details, which can lead to more efficient and concise code.

Here's a simple example of declarative programming in Python using list comprehensions:

# Declarative Programming Example using List Comprehensions

# Imperative approach: filtering odd numbers from a list
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
odd_numbers = []
for num in numbers:
    if num % 2 != 0:
        odd_numbers.append(num)

# Declarative approach: using list comprehension to filter odd numbers
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
odd_numbers = [num for num in numbers if num % 2 != 0]

print(odd_numbers)

In this example, we have a list of numbers and we want to filter out the odd numbers. Here's how the declarative approach using list comprehension works:

  • We define numbers as the original list of numbers.

  • We use a list comprehension ([num for num in numbers if num % 2 != 0]) to create a new list called odd_numbers.

  • Inside the list comprehension, we iterate over each element num in the numbers list.

  • The condition if num % 2 != 0 filters out the even numbers, leaving only the odd numbers.

  • The resulting list of odd numbers is assigned to the odd_numbers variable.

  • Finally, we print the odd_numbers list, which contains the filtered odd numbers.

This example demonstrates the declarative approach of using list comprehensions to express the desired outcome (filtering odd numbers) without explicitly specifying the step-by-step instructions to achieve it. The code becomes more concise and readable, emphasizing the intent rather than the implementation details.

Functional Programming

Functional programming takes the concept of functions a little bit further.

In functional programming, functions are treated as first-class citizens, meaning that they can be assigned to variables, passed as arguments, and returned from other functions.

Another key concept is the idea of pure functions. A pure function is one that relies only on its inputs to generate its result. And given the same input, it will always produce the same result. Besides, it produces no side effects (any change outside the function's environment).

With these concepts in mind, functional programming encourages programs written mostly with functions. It also defends the idea that code modularity and the absence of side effects makes it easier to identify and separate responsibilities within the codebase. This therefore improves the code maintainability.

Here's an example of functional programming in Python:

# Functional Programming Example in Python

def calculate_sum(numbers):
    # Use the built-in sum function to calculate the sum of the numbers
    return sum(numbers)

def calculate_average(numbers):
    # Calculate the sum using the calculate_sum function
    sum = calculate_sum(numbers)

    # Calculate the average by dividing the sum by the number of elements
    average = sum / len(numbers)

    # Return the calculated average
    return average

# Example usage
numbers_list = [1, 2, 3, 4, 5]
result = calculate_average(numbers_list)
print("Average:", result)

In this example, we have two functions: calculate_sum and calculate_average. These functions follow a functional programming approach.

The calculate_sum function uses the built-in sum function in Python, which takes a sequence of numbers and returns their sum. It directly applies the sum function to the numbers list without using any loops or mutating variables.

The calculate_average function utilizes the calculate_sum function to calculate the sum of the numbers. It then divides the sum by the length of the list to calculate the average.

The example demonstrates the use of higher-order functions and immutability, which are key concepts in functional programming. Functional programming focuses on writing code that is composed of pure functions, avoids mutable state, and emphasizes immutability and higher-order functions.

When you run this code, it will output the average of the numbers in the list, which in this case is 3.0.

Conclusion

As we've seen, programming paradigms are different ways in which we can face programming problems, and organize our code.

Imperative, procedural, functional, declarative, and object oriented paradigms are some of the most popular and widely used paradigms today. And knowing the basics about them is good for general knowledge and also for better understanding other topics of the coding world.

Last updated