Computer Programming Paradigms

A computer is calculator but it really is a super calculator on steroids. They are capable of performing trillions (depending on your computer) of accurate and reliable calculations per second. More than what any human being can consciously perform in their lifetime. In addition to all these, a computer can work all day all week without rest thus cheap labour.

Programming is about writing instructions for a computer in order to harness this accuracy, reliability, power and speed.

The problem however is that computer only understand binary (0’s and 1’s). This is because computers are made from transistors. Transistors can only have On or Off state. On, signifying 1’s while Off, signifying 0’s respectively. This is called Machine code or binary code.

In the early days of programming, computer programs were written in Machine Code.

A program in a non-structured language uses unstructured jumps to labels or instruction addresses. The lines are usually numbered or may have labels: this allows the flow of execution to jump to any line in the program. Look at the sample BASIC code above.

While writing computer instructions line after line (in a single file) may sound sexy, poetic and efficient, it is not!

When building a program, lines of code keep multiplying as you add more functionality. Eventually, the codebase becomes huge.

With unstructured paradigm it is close to impossible to remember the control flow of a complex program, because everything is convoluted and grouped together thus difficult to debug and modify. This is what is known as Spaghetti code.

Ah! 😩 the wonderful problem of modularity.

As a blogger, the first iteration of any article never gets published, even if it does, mistakes would need to be fixed, some parts will be remove or repositioned and so on. For example, i have revised this article more than 50 times!

My point? a program often needs to be updated to accommodate unforeseen changes or mistakes.

Computers in the 1950’s were slow, unreliable and hard to program, thus, only simple programs could be written for it but as computers started to become more powerful, non-structured programming was not going to be suitable to harness this power to solve complicated problems.

In our example above, lots of features are missing. A user may not always want to withdraw money. He might want to

view account balance

deposit money

transfer money

open account

close account and so on.

All of these can be implemented but you would have a mess of a code that is very hard to maintain individually.

In context, you would not be able change how money is deposited without reading all of the code until you get to the part where you need to make a change. Lack of modularity is why such code hard to maintain.

A full blown banking application is far too complex for Unstructured paradigm to handle, because of lack of modularity and inability to model complex things, stay tuned for OOP.

TLDR;

What actually makes a language to be classified as unstructured is when:

The language is flat: it does not allowed clear blocks of codes to be defined. Blocs are a group of statements that can be replaced by another block of any size. BASIC’s line numbering does not allow this.

The Use of Goto statements. GOTO allows highly unstructured spaghetti code. Whatever the theory will tell you. GOTO breaks the sequence (a numbered line cannot be sure that the previous line was executed, since a direct GOTO could have lead there), GOTO does allow selection or iteration only in combination with other statements.

You cannot call a subroutine (aka function, method or procedure) with a simple statement,

Structured Programming Paradigm

A program of any complexity contains too many details for a human brain to comprehend without help.

To address the pitfall of non-structured programming a Dutch Computer Scientist, Edsger W. Dijkstra, published an influential albeit controversial open letter titled “Go To Statement Considered Harmful” in 1968, which led to (in addition to other stimuli) the widespread adoption of Structured Programming. The letter outlined his position on the three control structures. They are:

If / else / then – Conditional

while / for – Iteration

block structures and sub-routines also known as functions or procedures or methods

According to Prof Dijkstra, the following qualities connote a Structured Programming Paradigm:

“Sequence”; ordered statements or subroutines executed in a particular order in which related events follow each other.

“Selection”; one or a number of statements is executed depending on the state of the program. This is usually expressed with keywords such as if..then..else..endif.

“Iteration”; a statement or block is executed until the program reaches a certain state, or operations have been applied to every element of a collection. This is usually expressed with keywords such as while, repeat, for or do..until.

Subroutines; callable units such as procedures, functions, methods, or subprograms are used to allow a sequence to be referred to by a single statement.

Blocks are used to enable groups of statements to be treated as if they were one statement.

In simpler language, a structured language should at least provide:

blocks (without line numbers that could break the flow of control anywhere: you enter and leave a block through clear ways)

variables that are local to a block to ensure modularity,

clean subroutines with parameter passing,

control flow statement that would allow to write a program without goto (even if this statement was included in the language for convenience).

Paradigms Based on Changing machine state

This is a paradigm that is used to classify programming languages based on their ability to change a computers’ state.

They include:

Imperative Paradigm – in which the programmer instructs the machine how to change its state

Declarative Paradigm- in which the programmer merely declares properties of the desired result, but not how to compute it

What does “State” mean?

A computer program stores data in variables, which represent storage locations in the computer’s memory. The contents of these memory locations, at any given point in the program’s execution, is called the program’s state. As the program is executed, its state may change — variables can change and the values that are stored in memory can also change.

However, some languages do not allow the changing of a computer state. Such languages can be classified under the Declarative programming paradigm.

Imperative Programming paradigm

This is a paradigm that allows us to instruct out program to change a computer state, and they consists of:

Procedural Languages eg C, Fortran, Pascal etc

Object Oriented Languages eg C++ , Java, Kotlin etc

Procedural Paradigm

A procedural paradigm is a style computer programming that follows, in order, a set of commands.

Although this style of programming is modular. It is not modular enough to handle big applications and can not efficiently model complex systems. Stay tuned for OOP!

Example 3

The “C” code below improves upon example 2

#include <stdio.h>
int main(){
printf("Hello, Welcome to My Bank!");
int preferedAction = getUserPreferedAction();
if (preferedAction == 1){ //
withdrawMoney(200)
}else if (preferedAction == 2) {
bool transferMoney(200, "1234567890")
}else{
// handle the situation
}
return 0;
}
int getUserPreferedAction(){
int preferedAction = -1;
/*
Here we implement the Logic to get User Input
on the action they want to perform.
1. for Withdraw Money
2. for Transfer Money etc
and we return the action that was selected
in the form of a number.
the input the user gives us, is what we will
use to change the state of preferedAction integer
Hence, imperative.
*/
return preferedAction;
}
bool withdrawMoney(int amountToWithdraw) {
/*
Here we implement the Logic to withdraw money.
and we return if it was successful or not
We are going to assume it is always successful
*/
return TRUE;
}
bool transferMoney(int amountToTransfer, char destinationAcoountNumber[]) {
/*
Here we implement the Logic to transfer Money to another account.
and we return if it was successful or not
We are going to assume it is always successful
*/
return TRUE;
}

Notice something?

Yes, the code above is not different than that of Structured Paradigm in Example 2. Each functionality is still grouped in sub-routines (or procedures) but with some styling, however, the styling is not enough to earn it a Paradigm class of its own.

Procedural Paradigm is a subset of Structured Paradigm, but there is no actual difference between the two.

So what actually differentiates them?

To put it simply, imperative programming can be structured or unstructured. Structured programming can be procedural or object-oriented.

So procedural is a subset of structured and the term is usually used to contrast with object-oriented.

Object Oriented Programming (OOP) Paradigm

Procedural paradigm was good. It was good enough for mid-sized applications but when it comes to large complicated real world applications (eg Enterprise Application), developers were not able to model code to mimic complicated real world systems, in a way that did not produce spaghetti code.

Object-oriented programming (OOP) is a programming paradigm based on the concept of “objects”, which can contain data, in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods).

Classes are used to model Systems. After modeling, they are used to create objects.

An object is what is created when you instantiate a class. Instantiating a class is like giving birth to a new child. A child has exact copies of the genes of his parent and will behave like his parent. In this context the Parent of the child is a class.

Let’s revisit our bank app. The code below models the attributes (properties) of a regular bank account holder (in terms of name, etc) and the things they can do with their accounts.

Advantages of OOP over Procedural

The concept of classes is what makes OOP game changing.

The main advantages are :

1. It is easy to model a real system as real objects are represented by programming objects in OOP. The objects are processed by their member data and functions. It is easy to analyze the user requirements.

2. With the help of inheritance, we can reuse the existing class to derive a new class such that the redundant code is eliminated and the use of existing class is extended. This saves time and cost of program.

3. In OOP, data can be made private to a class such that only member functions of the class can access the data. This principle of data hiding helps the programmer to build a secure program that can not be invaded by code in other part of the program.

4. With the help of polymorphism, the same function or same operator can be used for different purposes. This helps to manage software complexity easily.

Large problems can be reduced to smaller and more manageable problems. It is easy to partition the work in a project based on objects.

It is possible to have multiple instances of an object to co-exist without any interference i.e. each object has its own separate member data and function.

Declarative Programming paradigm

Declarative languages have no side effect, meaning they cannot change the state of a program

Declarative paradigms are known for their simple and easy to read (and understand) syntax. The reason you might want that is because some trivial things that might take many lines of code to implement in imperative programming may just take one line of code in declarative style of programming.

Summary

Complex Enterprise Apps and Games are built with OOP, embedded systems and low level stuff (like compilers, interpreters, device drivers etc) use procedural while in data analysis Functional is often preferred.

Modern programming languages are multi-paradigm so that you do not lack the strengths of other paradigms.

Congratulations on finishing this epic long article, thanks and come again!