Programing paradigms are the theories or ideas that help to shape the different languages that you use to create software. They represent the major characteristics of a programming language, dictating its behavior. It is, therefore, safe to say that a paradigm is just as important as a programming language’s syntax and semantics. Most popular programming languages use one of a few types of programming paradigm.

1. Imperative Programming

The imperative paradigm is one of the earliest approaches to programming, going as far back as the 1950s. This paradigm relies heavily on the use of variables, commands, and procedures. Imperative programming uses commands to inspect and update variables, storing state in a program. A combination of commands then creates a procedure. Data abstraction plays a crucial role in data representation, which facilitates loose coupling. One of the most popular languages that uses the imperative paradigm is C. This programming language only supports function procedures.

An Imperative Program Example

        #include <stdio.h>
#include <string.h>
  
struct Customer
{
    int CustomerId;
    char OrderNumber[20];
    char Name[30];
    float OrderTotal;
};
  
void main ()
{
    struct Customer John = {4000, "HK1001", "John Doe", 200.00};
    struct Customer Jane = {4001, "HK1002", "Jane Doe", 600.00};
  
    memcpy(Jane.Name , "Jane Jones", 10);
  
    printf ("The total cost for %s order number %s is: $%.2f",Jane.Name, Jane.OrderNumber, Jane.OrderTotal);
}

The C program above creates a Customer structure. The struct type is a prime example of data abstraction in C. The program demonstrates how commands can create, update, and display state — via the Jane structure variable. All these commands are in a main() function, which as a whole is a procedure that states how much money a customer should pay for an order. Executing the program above will produce the following output in your console:

        The total cost for Jane Jones order number HK1002 is: $600.00

2. Object-Oriented Programming

The object-oriented programming paradigm took off in the 1990s. This paradigm is a descendant of the imperative one. However, the object-oriented paradigm stores state in objects and not variables. Programming languages that use the object-oriented paradigm often handle complex applications better. The paradigm’s core features are objects, classes, data encapsulation, inheritance, and polymorphism. A class is the foundational component of an object-oriented program. Some classes inherit properties and operations from other classes. Programmers describe this as a parent-child relationship. It falls under the category of sub-type polymorphism. Classes contain tools to hide and protect sensitive data through encapsulation. Once you have defined a class, you can then use it to create objects. Three of the more popular programming languages that use the object-oriented paradigm are Java, C++, and Python.

An Object-Oriented Program Example

This application demonstrates most of the features of an object-oriented programming language, Java. A specific type of customer inherits behavior from a more general type. All customers implement an interface. The specific customer type overrides a method from the interface.

The Discountable.java File

        public interface Discountable {
    public void grandTotal(String orderNumber, double total);
}

The code above creates an interface. In Java, an interface is another example of polymorphism. It allows entities that are not directly related to access the same properties, like the grandTotal method. This application focuses on customers, but an employee class could also have use for the Discountable interface.

The Customer.java File

        public class Customer implements Discountable {
    protected int customerId;
    protected String customerName;
    protected String customerCode;
 
    public Customer() {
        this.customerId = 0;
        this.customerName = "";
        this.customerCode = "";
    }
 
    public Customer(int customerId, String customerName, String customerCode) {
        this.customerId = customerId;
        this.customerName = customerName;
        this.customerCode = customerCode;
    }
 
    public int getCustomerId() {
        return customerId;
    }
 
    public void setCustomerId(int customerId) {

             this.customerId = customerId;

      }

      public String getCustomerName() {

             return customerName;

      }

      public void setCustomerName(String customerName) {

             this.customerName = customerName;

      }

      public String getCustomerCode() {

             return customerCode;

      }



      public void setCustomerCode(String customerCode) {

             this.customerCode = customerCode;

      }

     

      public double customerType(String customerCode) {

             double discount = 0;
    
             if (customerCode.toLowerCase().equals("pre")) {
                    discount = 0.10;
             } else if (customerCode.toLowerCase().equals("gen")) {
                    discount = 0.02;
             } else if (customerCode.toLowerCase().equals("new")) {
                    discount = 0.05;
             }

             return discount;

      }
 
    @Override
    public void grandTotal(String orderNumber, double total) {
        double discount = customerType(customerCode);
        double discountPercentage = total * discount;
        double finalTotal = total - discountPercentage;
 
        System.out.println("For " + getCustomerName()
            + " order Number " + orderNumber + " the grand total is: $" + finalTotal);
    }
}

The code above creates a Customer class. It implements the Discountable interface, then uses its method to calculate and display a grand total, based on the customer’s category. The protected keyword in the code above is an example of data encapsulation; it restricts access to the data created through this class. So, only subclasses (or child classes) of the Customer class will have access to its data.

The NewCustomer.java File

        <strong>public</strong> <strong>class</strong> NewCustomer <strong>extends</strong> Customer {

      <strong>public</strong> NewCustomer() {

             <strong>super</strong>();

      }

     

      <strong>public</strong> NewCustomer(<strong>int</strong> customerId, String customerName, String customerCode) {

             <strong>super</strong>(customerId, customerName, customerCode);

      }



}

The code above creates a NewCustomer class that extends the Customer class. This Java class uses inheritance to represent a parent-child relationship with the Customer class. The NewCustomer is the child in the relationship, so, it has access to all the properties in the Customer class. It imports the Customer class attributes using the super() method.

The App.java File

        <strong>public</strong> <strong>class</strong> App {

      <strong>public</strong> <strong>static</strong> <strong>void</strong> main(String[] args) {

          Customer Jane = <strong>new</strong> NewCustomer(4001, "Jane Jones", "new");

          Jane.grandTotal("HK1002", 600);

      }

}

The code above creates an executable App class. This class creates a Customer object (Jane) and through polymorphism makes Jane a NewCustomer. Finally, it generates the grand total for Jane’s order. Executing the program above will generate the following output in the console:

        For Jane Jones order Number HK1002 the grand total is: $570.0

3. Functional Programming

The key concepts of this paradigm are expressions, functions, parametric polymorphism, and data abstraction. Expressions are the fundamental components of the functions used by functional programming languages. Parametric polymorphism is one of three types of polymorphism. This type facilitates generic programming through functions and types. JavaScript is one of the most popular functional programming languages.

A Functional Program Example

        const Customer = {

   IdNumber: 1002,

   Name: 'Jane Jones',

   CustomerCode: 'new'

}



const main = (customer, func, value) => {

    var total = func.apply(null, [ customer.CustomerCode, value ]);

    console.log(`${customer.Name} total is: ${total}`);

}



const grandTotal = (CustomerCode, total) => {

   if (CustomerCode == "new") {

       discount = total * 0.05;

       mainTotal = total - discount;

       return mainTotal;

   } else if (CustomerCode == "pre") {

       discount = total * 0.10;

       mainTotal = total - discount;

       return mainTotal;

   }

}



main(Customer, grandTotal, 600);

The JavaScript program above has an object literal and two functions. It declares each of the functions as an expression using the JavaScript arrow function. The main() function is a higher-order function. It takes the grandTotal function as one of its arguments, then calls that function. This is also an example of parametric polymorphism. The grandTotal() function contains several expressions, and the Customer object is an example of data abstraction. The program above generates the following output in the console:

        Jane Jones total is: $570

The Complexity of Programing Languages

A programing language may embody the concepts of one programming paradigm, but that doesn’t mean it’s limited to one paradigm. Many of the popular programming languages (such as Python, Java, JavaScript, and C++) are multi-paradigm languages. Some programming paradigms, such as the imperative and object-oriented paradigms, are also related. But despite this kinship, there are some significant differences.